ListView W-1

Stelle Fragen zur Programmierung mit Autohotkey

Moderator: jNizM

effel
Posts: 392
Joined: 16 Jan 2018, 13:34

ListView W-1

Post by effel » 09 Jun 2021, 23:59

Hallo, ich habe meinen Code nun soweit gestaltet bekommen, dass sich die Anzahl der Spalten der ListView selbst berechnet.

Mit LW_W := (spalten * 70) berechne ich dann die Gesamtbreite der ListView

Damit stellt sich die Gui in Abhängigkeit von Range selbst auf ihre Größe ein.

Das passt auch ganz gut, aber nur wenn es um die 'üblichen' Zahlenkolonnen geht, die man in der Regel in eine Excel Tabelle eingibt.

Steht aber z.b. beschreibender Text in breiten Zellen, sieht es gleich unschön aus.

Kann man die ListView auch so konfigurieren das sie automatisch ihre optimale Breite einstellt?

Ich habe w400 h400 mal weggelassen, oder w-1 wie bei den Bildern versucht, aber das geht garnicht

Ich brauche sowas wie LV_ModifyListView("AutoHdr")

Danke furs lesen 🙂

Code: Select all

;a1 bis c20 mit ComObjActive Excel.Application
;https://www.autohotkey.com/boards/viewtopic.php?f=9&t=91442&p=404134#p404134

ZeilenArray := SpreadsheetRange("a1:d20")
gui show
Return

SpreadsheetRange(range) {
split := StrSplit(range,":")
lf := (asc(SubStr(split.2,1,1)) - 96)
XlApp := ComObjActive("Excel.Application")
For k in XlApp.Range(range) {
        ++aindex
value := k.value
if value is number
values .= Format("{:.2f}", k.value) "|"
else 
	values .= k.value "|"
	if (aindex=lf) {
        aindex=
        values .= "`n"
}}
Loop,% lf
ListViewCols .= chr(64 + A_Index) "|"
LW_W := (lf * 70)
Gui +Resize
Gui, Add, ListView, w%LW_W% h400,% "#|" ListViewCols
Loop, Parse, values, `n
Lv_Add("",A_index, StrSplit(A_LoopField,"|")*)
Loop, % LV_GetCount("Columns")
LV_ModifyCol(A_Index, "AutoHdr")
; Array aufbauen ; https://www.autohotkey.com/boards/viewtopic.php?p=54496#p54496
ZeilenArray := StrSplit(values, "`n", "`r")    ; ZeilenArray muss nicht vorher als Array deklariert werden
For Index, Zeile In ZeilenArray                ; Schleife über alle Zeilen
   ZeilenArray[Index] := StrSplit(Zeile, "|")  ; Aktuelles ZeilenElement mit dem SpaltenArray aus StrSplit() überschreiben
return ZeilenArray
}
Last edited by effel on 10 Jun 2021, 06:47, edited 1 time in total.

User avatar
LuckyJoe
Posts: 297
Joined: 02 Oct 2013, 09:52

Re: ListView W-1

Post by LuckyJoe » 10 Jun 2021, 01:36

Hi effel,

meinst du "LV_ModifyCol" (s. Hilfe)?
Herzliche Grüße aus dem Rheinland
Lucky Joe

effel
Posts: 392
Joined: 16 Jan 2018, 13:34

Re: ListView W-1

Post by effel » 10 Jun 2021, 06:10

Hallo LuckyJoe,

Danke für deine Teilnahme,

nein ich meinte die Gesamtbreite der Gui die eigentlich nur aus einer ListView besteht.
Diese soll je nach Inhalt auch, so ( wie 'AutoHdr' ) automatisch ihre Breite anpassen

Unbenannt.png
Unbenannt.png (34.13 KiB) Viewed 739 times

just me
Posts: 8042
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ListView W-1

Post by just me » 10 Jun 2021, 08:36

Moin,

nachdem Du die Spalten per 'AutoHdr' angepasst hast, probier mal

Code: Select all

; ======================================================================================================================
; LV_EX_CalcViewSize - Calculates the approximate width and height required to display a given number of items.
; ======================================================================================================================
LV_EX_CalcViewSize(HLV, Rows := 0) {
   ; LVM_APPROXIMATEVIEWRECT = 0x1040 -> http msdn.microsoft.com /en-us/library/bb774883(v=vs.85).aspx  Broken Link for safety
   SendMessage, 0x1040, % (Rows - 1), 0, , % "ahk_id " . HLV
   Return {W: (ErrorLevel & 0xFFFF), H: (ErrorLevel >> 16) & 0xFFFF}
}
Das gibt Dir ein Objekt mit den Schlüsseln W und H mit den berechneten Werten zurück. Das sind Pixel, allerdings nicht skaliert. Du kannst ja mal schauen, ob die Breite passt.

Quelle: LV_EX.ahk

effel
Posts: 392
Joined: 16 Jan 2018, 13:34

Re: ListView W-1

Post by effel » 10 Jun 2021, 17:15

Hallo Just Me,

vielen Dank.

Ich habe es nun in verschiedenen Versionen getestet, und sehe, das die h&w Werte annähernd passen.

Aber ich muss dann die angezeigten Werte 'nachträglich' eintragen neu starten, damit die ListView die richtige Größe bekommt.

Das mache ich bestimmt noch nicht richtig.

Code: Select all

FileEncoding, UTF-8
#SingleInstance, force
range := "a1:u20"
split := StrSplit(range,":")                          ; ListViewCols
lf := (asc(SubStr(split.2,1,1)) - 96)                 ; ListViewCols
Loop,% lf                                             ; ListViewCols
ListViewCols .= chr(64 + A_Index) "|"                 ; ListViewCols
;msgbox,,d=4,% lf
XlApp := ComObjActive("Excel.Application")
For k in XlApp.Range(range) {
        ++aindex
        L := k.value
        L := RTrim(L,".0")
	Values .= L "|"
	if (aindex=lf) {
        aindex=
        Values .= "`n"
}}
  Gui, Add, ListView, h381 w1150 hwndHLVA,% "#|" ListViewCols
;  Gui, Add, ListView, h390 w630 hwndHLVA,% "#|" ListViewCols
; Gui, Add, ListView,           hwndHLVA,% "#|" ListViewCols
Loop, Parse, Values, `n
Lv_Add("",A_index, StrSplit(A_LoopField,"|")*)
lvc := LV_GetCount()
Loop, % LV_GetCount("Columns")
LV_ModifyCol(A_Index, "AutoHdr")
gui, show

LVA := LV_EX_CalcViewSize(HLVA,lvc)
LVAH := lva.h
LVAW := lva.w
msgbox,,listViewHoeheBreite,% LVAH "<>" LVAW 

return



; ======================================================================================================================
; LV_EX_CalcViewSize - Calculates the approximate width and height required to display a given number of items.
; ======================================================================================================================
LV_EX_CalcViewSize(HLV, Rows := 0) {
   ; LVM_APPROXIMATEVIEWRECT = 0x1040 -> http msdn.microsoft.com /en-us/library/bb774883(v=vs.85).aspx  Broken Link for safety
   SendMessage, 0x1040, % (Rows - 1), 0, , % "ahk_id " . HLV
   Return {W: (ErrorLevel & 0xFFFF), H: (ErrorLevel >> 16) & 0xFFFF}
}
; ======================================================================================================================
;
; ======================================================================================================================

Unbenannt.png
Unbenannt.png (60.95 KiB) Viewed 691 times

effel
Posts: 392
Joined: 16 Jan 2018, 13:34

Re: ListView W-1

Post by effel » 10 Jun 2021, 20:01

Ich habe es herausgefunden

GuiControl, Move, SysListView321, w%LVAW% h%LVAH%

Code: Select all

range := "a1:i13"
split := StrSplit(range,":")                          ; ListViewCols
lf := (asc(SubStr(split.2,1,1)) - 96)                 ; ListViewCols
Loop,% lf                                             ; ListViewCols
ListViewCols .= chr(64 + A_Index) "|"                 ; ListViewCols
;msgbox,,d=4,% lf
XlApp := ComObjActive("Excel.Application")
For k in XlApp.Range(range) {
        ++aindex
        L := k.value
        L := RTrim(L,".0")
	Values .= L "|"
	if (aindex=lf) {
        aindex=
        Values .= "`n"
}}
Gui, Add, ListView, hwndHLVA,% "#|" ListViewCols
Loop, Parse, Values, `n
Lv_Add("",A_index, StrSplit(A_LoopField,"|")*)
lvc := LV_GetCount()
Loop, % LV_GetCount("Columns")
LV_ModifyCol(A_Index, "AutoHdr")
LVA := LV_EX_CalcViewSize(HLVA,lvc)
LVAH := (lva.h + 30)
LVAW := (lva.w + 30)
if (LVAH>A_ScreenHeight)
LVAH := 600
if (LVAW>A_ScreenWidth)
LVAW := (A_ScreenWidth - 100)
GUIH := (LVAH + 10)
GUIW := (LVAW + 20)
;msgbox,,listViewHoeheBreite,% LVAH "<>" LVAW ,1
GuiControl, Move, SysListView321, w%LVAW% h%LVAH%
;GuiControl, Move, SysListView321,% "w" (LVAW + 20) "h" (LVAH + 10)
gui, show, w%GUIW% h%GUIH%
return

; ======================================================================================================================
; LV_EX_CalcViewSize - Calculates the approximate width and height required to display a given number of items.
; ======================================================================================================================
LV_EX_CalcViewSize(HLV, Rows := 0) {
   ; LVM_APPROXIMATEVIEWRECT = 0x1040 -> http msdn.microsoft.com /en-us/library/bb774883(v=vs.85).aspx  Broken Link for safety
   SendMessage, 0x1040, % (Rows - 1), 0, , % "ahk_id " . HLV
   Return {W: (ErrorLevel & 0xFFFF), H: (ErrorLevel >> 16) & 0xFFFF}
}
; ======================================================================================================================


garry
Posts: 2760
Joined: 22 Dec 2013, 12:50

Re: ListView W-1

Post by garry » 11 Jun 2021, 05:25

danke für die scripts
hier ein komplizierter script , bei button Print zählt es die Buchstaben , mit nonproportional script denn im Editor ausgedruckt

Code: Select all

;- idea = replace comma with a delimiter ascii=127 at least add another delimiter which not exists in column
;       = print formatted / font notproportinal like Lucida Console etc 
;       = show content from clicked ROW and ALL-contents from ROW
#warn
Gui,2: -DPIScale
Gui,2:Font,s12 cBlack,Lucida Console
Gui,2:Color,Black,Black
wa:=A_screenwidth,ha:=A_screenHeight,xx:=100
transform,s,chr,127   ;- delimiter
Title=LV_TEST         ;- print notepad with non proportional characters 
TxtInfo = 
(LTrim Join`r`n
"Head1a","1ca","100-253a","Info123a","1a","Info1a1, Info2a2, Info3a3","TxtStarta"
"Head2b","1cb","100-253b","Info123----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartb"
"Head3b","1cb","100-253c","Info123----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartb"
"Head4b","1cb","100-253d","Info123----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartb"
"Head5b","1cb","100-253e","Info12355555----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaz"
"Head6b","1cbaaaaz","100-253f","Info123----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartb",
"Head7b","1cb","100-253g","Info123----------b","1b","Info1b1aaaaaaaaaaaaz, Info2b2, Info3b3","TxtStartb"
"Head8b","1cb","100-253h","Info123----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartb",
"Head9b","1cb","100-253i","Info123----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartb",
"Head10b","1cb","100-253j","Info123----------b","1b","Info1b1, Info2b2, Info3b3aaaaaaaaaaaaaaaaaaaz","TxtStartb"
"Head11b","1cb","100-253k","Info123----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartb"
"Head12b","1cb","100-253l","Info123----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartb"
"Head13b","1cb","100-253m","Info123----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartb"
"Head14b","1cb","100-253n","Info123----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartb"
"Head15b","1cb","100-253o","Info123----------b","1b","Info1b1, Info2b2aaaaaaaaaz, Info3b3","TxtStartb"
"Head16b","1cb","100-253p","Info123----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartb"
"Head17b","1cb","100-253q","Info123----------b","1b","Info1b1, Info2b2, Info3b3","TxtStartb"
)
F1 =%a_scriptdir%\TxtInfo.txt
IfExist %F1%
	FileDelete %F1%
FileAppend %TxtInfo%, %F1%
h:=(ha*15)/xx
Gui,2:Add, ListView,  backgroundSilver grid x0 y0 h%h%  +hscroll altsubmit vLV1 gMLV2  +HWNDHLV, A|B|C|D|E|F|G
y:=(ha*16)/xx,h:=(ha*2.5)/xx,w:=(wa*5)/xx
Gui,2:add,button, x10 y%y% w%w% h%h% gPrint2,PRINT
gosub,fill
Gui,2:show,x10 y10 w%gw%,%title%
return
;-----------------
2Guiclose:
exitapp
;-----------------
fill:
Gui,2:submit,nohide
Gui,2:default
LV_Delete()
fileread,aa,%f1%
dlm:=s                                     ;- delimiter
stringreplace,aa,aa,`"`,,`"%s%,all
stringreplace,aa,aa,`",,all
for each, Line in StrSplit(aa, "`n", "`r")
{
if line=
  continue
Cx := StrSplit(Line,dlm)
stringreplace,cx,cx,%s%,`;,all
LV_Add("",Cx*)
}

/*
total:=LV_GetCount("Col")
Loop,%total%
  LV_ModifyCol(A_Index, "AutoHdr")
*/

wx:=0
wt:=0
total:=LV_GetCount("Col")
Loop,%total%
  {
  LV_ModifyCol(A_Index, "AutoHdr")
  W%A_Index% := LV_GetColumnWidth(HLV, A_Index)     ;- column width
  wx:= % W%A_Index%
  wt:=(wt+wx)            ;- width from all columns
  }
df1:=(ha*2.5)/xx         ;- difference width / add to listview
df2:=(ha*3.5)/xx         ;- difference width / add to GUI
gw :=wt+df2              ;- total width from all columns for GUI-width
lw :=wt+df1              ;- listview width 
h  :=(ha*15)/xx,
GuiControl,2: Move, SysListView321, w%lw% h%h%  ;- define listview-width
return
;-----------------
mlv2:
Gui,2:default
Gui,2:Listview,LV1
RN:=LV_GetNext("C")
GC:=LV_GetCount()
Total:=LV_GetCount( "Col" )         ;- columns in the listview.
  if (rn=0)
    return
Row := A_EventInfo
Col := LV_SubitemHitTest(HLV)
LV_GetText(result, Row, Col)
  all:=""
  loop,%total%
    c%a_index%:=""
  Loop,%total%
    {
    LV_GetText(colx,a_eventinfo,a_index)
	c%a_index%:=colx
	all .= colx . ";"
	}
  stringtrimright,all,all,1	

  If A_GuiEvent = normal
     {
     ;LV_GetText(C1,A_EventInfo,1)      ;- show only column-1
     msgbox, 262208,ROW&COLUMN ,You clicked column=%col% in row=%row%  =>> %result%`n-------------------`nALL=`n%all%,
     }
return
;-----------------
;============ case-1 PRINT_WYS use non proportional script in editor like Lucida Console ====================
print2:
;-- check maximal lenght from each column ---
FilePrint=%a_desktop%\%title%_WYS.txt
ifexist,%fileprint%
   filedelete,%fileprint%
ControlGet, Listx, List, , SysListView321,%title%
dlm:=";"                                                ;- <<< maybe add a new delimiter which not exists in column
stringreplace,listx,listx,`t,%dlm%,all
tx:=""
loop,%total%
  T%a_index%:=0
loop,%total%
  L%a_index%:=0
	Loop,parse,listx,`n,`r
     {
	 lr=%a_loopfield%
     if lr=
       continue
	 i=0
	 loop,%total%                           ;- get max lenght from x columns ( characters )
	    {
		i++
        StringSplit,A,lr,%dlm%
        stringlen,L%i%,A%i%
        if (T%i%<L%i%)
           T%i%:=(L%i%+1)                   ;- maximal lenght columnX+1
		}
	 }
;- x columns
loop,%total%	 
 Tx .= "{:" . T%a_index% . "}" . dlm
stringtrimright,tx,tx,1
msgbox, 262208,COLUMN-WIDTH-CHARACTERS+1 ,%tx%
loop,%total%
  a%a_index%:=""
lr=
e:=""
Loop, parse,listx, `n,`r
 {
 lr=%a_loopfield%
 if lr=
    continue
 a :=StrSplit(lr,dlm )
 e .= Format(tx . "`r`n",a*)
 }
fileappend,%e%,%fileprint%,utf-8
run,%fileprint% 
e=
a=
listx=
return
;=============================================

;================== function just me ==============================
; https://autohotkey.com/board/topic/80265-solved-which-column-is-clicked-in-listview/
LV_SubitemHitTest(HLV) {
   ; To run this with AHK_Basic change all DllCall types "Ptr" to "UInt", please.
   ; HLV - ListView's HWND
   Static LVM_SUBITEMHITTEST := 0x1039
   VarSetCapacity(POINT, 8, 0)
   ; Get the current cursor position in screen coordinates
   DllCall("User32.dll\GetCursorPos", "Ptr", &POINT)
   ; Convert them to client coordinates related to the ListView
   DllCall("User32.dll\ScreenToClient", "Ptr", HLV, "Ptr", &POINT)
   ; Create a LVHITTESTINFO structure (see below)
   VarSetCapacity(LVHITTESTINFO, 24, 0)
   ; Store the relative mouse coordinates
   NumPut(NumGet(POINT, 0, "Int"), LVHITTESTINFO, 0, "Int")
   NumPut(NumGet(POINT, 4, "Int"), LVHITTESTINFO, 4, "Int")
   ; Send a LVM_SUBITEMHITTEST to the ListView
   SendMessage, LVM_SUBITEMHITTEST, 0, &LVHITTESTINFO, , ahk_id %HLV%
   ; If no item was found on this position, the return value is -1
   If (ErrorLevel = -1)
      Return 0
   ; Get the corresponding subitem (column)
   Subitem := NumGet(LVHITTESTINFO, 16, "Int") + 1
   Return Subitem
}
;-------------------------------------------------------------------------------

; ==============================================================================
; Breite einer Spalte in einem ListView ermitteln
; LV_GetColumnWidth(hLV, iCol)
; hLV    - HWND des ListView
; iCol   - 1-basierter Spaltenindex
; ==============================================================================
LV_GetColumnWidth(hLV, iCol) {
   LVM_GETCOLUMNWIDTH := 0x101D
   SendMessage, %LVM_GETCOLUMNWIDTH%, % (--iCol), 0, , ahk_id %hLV%
   Return ErrorLevel
}
;==================== END SCRIPT =====================================


effel
Posts: 392
Joined: 16 Jan 2018, 13:34

Re: ListView W-1

Post by effel » 11 Jun 2021, 18:31

garry wrote:
11 Jun 2021, 05:25
danke für die scripts
hallo garry, danke zurück, nonproportional, gute idee, muss ich mehrfach lesen 😵

Ich habe an meinem Code noch etwas weiter geschrieben, und möchte versuchen, die erzeugten GUIs die ich mit der Maus auf dem Screen angeordnet habe...

... beim nächsten Programm-Start automatisch so anordnet. Dazu habe ich erstmal alle GUI Daten im LOG1 Array gespeichert,

Unbenannt.png
Unbenannt.png (11.44 KiB) Viewed 615 times
Unbenannt.png
Unbenannt.png (30.34 KiB) Viewed 612 times
aber wie ich an die Koordinaten der verschobenen Elemente komme... da stehe ich grade auf dem Schlauch.

A_GuiX und A_GuiY sind wohl nur augenscheinlich dafür zuständig.

Ich bin offen für Vorschläge, wenn man das besser angehen kann.

Danke fürs lesen einen schönen Tag euch

Code: Select all

FileCopy, % A_ScriptFullPath, % A_ScriptDir "\save\" A_ScriptName " save " A_Now " .ahk"
FileEncoding, UTF-8
#SingleInstance, force
LOG1 := object()
GuiArr := []
range := "a1:d20"
gosub newc
gosub LoadLog
;FillLV(log1)

return

Newc:
++c
Gui, %c%:Submit, nohide
Critical Off  ; Selbst wenn Critical On nie verwendet wurde.
Sleep -1
split := StrSplit(range,":")                          ; ListViewCols
lf := (asc(SubStr(split.2,1,1)) - 96)                 ; ListViewCols
Loop,% lf                                             ; ListViewCols lf = "a2:d7" = d = 4
ListViewCols .= chr(64 + A_Index) "|"                 ; ListViewCols lf = 4
XlApp := ComObjActive("Excel.Application")
For k in XlApp.Range(range) {
        ++aindex
        L := k.value
        L := RTrim(L,".0")
	Values .= L "|"
	if (aindex=lf) {
        aindex=
        Values .= "`n"
}}
Gui, %c%:New
Gui, %c%:+hwndHGui%c%
Gui, %c%:Default

Gui, %c%:Add, Edit, xm w90 vEDITA,% split.1 " : " split.2 
Gui, %c%:Add, Button, x+10 gNewData, ok
Gui, %c%:Add, ListView, xm hwndHLVA,% "#|" ListViewCols
Loop, Parse, Values, `n
Lv_Add("",A_index, StrSplit(A_LoopField,"|")*)
lvc := LV_GetCount()
Loop, % LV_GetCount("Columns")
LV_ModifyCol(A_Index, "AutoHdr")
LVA := LV_EX_CalcViewSize(HLVA,lvc)
LVAH := (lva.h + 30)
LVAW := (lva.w + 30)
if (LVAH>A_ScreenHeight)
LVAH := 600
if (LVAW>A_ScreenWidth)
LVAW := (A_ScreenWidth - 100)
GUIH := (LVAH + 40)
GUIW := (LVAW + 20)
;msgbox,,listViewHoeheBreite,% LVAH "<>" LVAW ,1
GuiControl, %c%:Move, SysListView321, w%LVAW% h%LVAH%
Gui, %c%:show, w%GUIW% h%GUIH%,% A_GuiX A_Space A_GuiY " gui: " c
xguiW := A_GuiWidth
xguiH := A_GuiHeight
xguiX := A_GuiX
xguiY := A_GuiY
gosub LoadLog
for i, var in LOG1["gui#" . c . "_lva"]
varall .= "gui#" . c . "_LV_EX_" i "`t" (isObject(var) ? "Object" : var) "`n"
for i, var in LOG1
varall .= i "`t" (isObject(var) ? "Object" : var) "`n"
MsgBox,,, % varall,1
varall:=""
return
 
LoadLog:
LOG1["gui#" . c . "_A_DefaultGui"] := (A_DefaultGui ? A_DefaultGui : "empty")
LOG1["gui#" . c . "_rows"]         := (lvc ? lvc : "empty")
LOG1["gui#" . c . "_lva"]          := (lva ? lva : "empty")
LOG1["gui#" . c . "_lvah"]         := (lvah ? lvah : "empty")
LOG1["gui#" . c . "_lvaw"]         := (lvaw ? lvaw : "empty")
LOG1["gui#" . c . "_guih"]         := (guih ? guih : "empty")
LOG1["gui#" . c . "_guiw"]         := (guiw ? guiw : "empty")
LOG1["gui#" . c . "_A_GuiHeight"]  := (xguiH ? xguiH : "empty")
LOG1["gui#" . c . "_A_GuiWidth"]   := (xguiW ? xguiW : "empty")
LOG1["gui#" . c . "_A_GuiX"]       := (xguiX ? xguix : "empty")
LOG1["gui#" . c . "_A_GuiY"]       := (xguiY ? xguiY : "empty")
LOG1["gui#" . c . "_GuiHWND"]      := (HGui%c%)
LOG1["gui#" . c . "_hwndHLVA"]     := (HLVA)
;LOG1["gui#" . c . "_Values"]      := ":`n" Values
LOG1["gui#" . c . "_range"]        := range
LOG1["gui#" . c . "_rangeA"]       := split.1
LOG1["gui#" . c . "_rangeb"]       := split.2
;LOG1["gui#" . c . "_XlApp"]        := XlApp
LOG1["gui#" . c . "_cools"]        := (lf ? lf : "empty")
LOG1["gui#" . c . "_coolsCHR"]     := ((chr(64 + lf)) ? (chr(64 + lf)) : "empty")
;GuiArr.Push(LOG1)
Gui, FILL%c%:NEW
Gui, FILL%c%:Add, ListView, w350 r21 hwndHFillLVIDa Grid cBlack BackgroundFFDD99, Key1|Key2|Key3|Key4|Key5|Value
tmp:=FillLV(log1)
Gui, FILL%c%:Show, , GuiStats -> ListView
MsgBox,,, % jsonFile := (AhkToJSON(LOG1, A_Space)),1
Gui, JsonFILL%c%:NEW
Gui, JsonFILL%c%:Add, ListView, w350 r21 hwndHFillLVIDb Grid cBlack BackgroundFFDD99, Key1|Key2|Key3|Key4|Key5|Value
Loop, Parse, jsonfile, `n 
RI := LV_Add("", A_Index, A_LoopField)
Loop, % LV_GetCount("Columns")
LV_ModifyCol(A_Index, "AutoHdr", A_Index)
Gui, JsonFILL%c%:Show, , Json -> ListView
return

NewData:
ListViewCols:=""
Values:=""
Gui, %c%:Submit, nohide
GuiControlGet, range, , EDITA
_range := range
range := strReplace(range,A_Space)
gosub newc
;GuiControlSet, , _range, EDITA
;GuiControl,,EDITA, %w_range%
;MsgBox,,, % range,1
Return

GuiClose:
        reload
GuiEscape:
	Gui, Hide
Return
; ======================================================================================================================
; LV_EX_CalcViewSize - Calculates the approximate width and height required to display a given number of items.
; ======================================================================================================================
LV_EX_CalcViewSize(HLV, Rows := 0) {
   ; LVM_APPROXIMATEVIEWRECT = 0x1040 -> http msdn.microsoft.com /en-us/library/bb774883(v=vs.85).aspx  Broken Link for safety
   SendMessage, 0x1040, % (Rows - 1), 0, , % "ahk_id " . HLV
   Return {W: (ErrorLevel & 0xFFFF), H: (ErrorLevel >> 16) & 0xFFFF}
}
; ======================================================================================================================
AhkToJSON(obj, indent := "") {
   static Doc, JS
   if !Doc {
      Doc := ComObjCreate("htmlfile")
      Doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
      JS := Doc.parentWindow
      ( Doc.documentMode < 9 && JS.execScript() )
   }
   if indent|1 {
      if IsObject( obj ) {
         isArray := true
         for key in obj {
            if IsObject(key)
               throw Exception("Invalid key")
            if !( key = A_Index || isArray := false )
               break
         }
         for k, v in obj
            str .= ( A_Index = 1 ? "" : "," ) . ( isArray ? "" : """" . k . """:" ) . %A_ThisFunc%(v, true)

         Return isArray ? "[" str "]" : "{" str "}"
      }
      else if !(obj*1 = "" || RegExMatch(obj, "^-?0|\s"))
         Return obj
      
      for k, v in [["\", "\\"], [A_Tab, "\t"], ["""", "\"""], ["/", "\/"], ["`n", "\n"], ["`r", "\r"], [Chr(12), "\f"], [Chr(8), "\b"]]
         obj := StrReplace( obj, v[1], v[2] )

      Return """" obj """"
   }
   sObj := %A_ThisFunc%(obj, true)
   Return JS.eval("JSON.stringify(" . sObj . ",'','" . indent . "')")
}

;#################
class CaseSenseList
{
   __New() {
      ObjRawSet(this, "_list_", [])
   }
   
   __Delete() {
      this.SetCapacity("_list_", 0)
      ObjRawSet(this, "_list_", "")
   }
   
   __Set(key, value) {
      for k, v in this._list_ {
         if !(v[1] == key)
            continue
         v[2] := value
         keyExist := true
      } until keyExist
      if !keyExist
         this._list_.Push([key, value])
      Return value
   }
   
   __Get(key) {
      if (key == "_list_")
         Return
      for k, v in this._list_ {
         if (v[1] == key)
            Return v[2]
      }
   }
   
   _NewEnum() {
      Return new this._CustomEnum_(this._list_)
   }
   
   class _CustomEnum_
   {
      __New(list) {
         this.i := 0
         this.list := list
      }
      
      Next(ByRef k, ByRef v := "") {
         if ++this.i <= this.list.Length() {
            k := this.list[this.i, 1]
            v := this.list[this.i, 2]
            Return true
         }
      }
   }
   
   Count() {
      Return this._list_.Length()
   }
   
   Delete(key) {
      for k, v in this._list_
         continue
      until v[1] == key && keyExist := true
      Return keyExist ? this._list_.RemoveAt(k)[2] : ""
   }
   
   HasKey(key) {
      for k, v in this._list_
         if (v[1] == key)
            Return true
      Return false
   }
}
;############################################################################

#NoEnv
SetBatchLines, -1
/*
TestX := {}
TestX["A"] := 1
TestX["B",22] := 2
TestX["C",22,33] := 3
TestX["C",22,34] := "3b"
TestX["D",22,33,44] := 4
TestX["E",22,33,44,55] := 5
TestX["Aaa"] := 1
TestX["Bbb",22] := 2
TestX["Ccc",22,33] := 3
TestX["Ccc",22,34] := "3b"
TestX["Ddd",22,33,44] := 4
TestX["Eee",22,33,44,55] := 5
Loop 9
   TestX["FFF" A_Index,22  A_Index, A_Index,44  A_Index,5 A_Index] :=  A_Index
*/

;FillLV(TestX)

FillLV(Arr, Row := "", Recursive := 0) {
;static VFillLVID
   For K, V In Arr {
      If (Recursive)
         Row .= "`t" . K
      Else
         Row := K
      If IsObject(V)
         FillLV(V, Row, 1)
      Else {
         RI := LV_Add("", StrSplit(Row, "`t")*)
         LV_Modify(RI, "Col6", V)
      }
   }
   Loop, % LV_GetCount("Col")
      LV_ModifyCol(A_Index, "AutoHdr")
;Gui, FillLVID:show ; , w%GUIW% h%GUIH%,% A_GuiX A_Space A_GuiY " gui: " c
}
20210612010100-Monitor-1.jpg
20210612010100-Monitor-1.jpg (287.86 KiB) Viewed 624 times

just me
Posts: 8042
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ListView W-1

Post by just me » 12 Jun 2021, 03:42

Moin,

viele der internen A_ Variablen werden nur unter bestimmten Bedingungen bereitgestellt und gefüllt. Dazu gehören auch

Code: Select all

;  GuiContextMenu- und GuiDropFiles-Ereignisse:
A_GuiX
A_GuiY
; GuiSize-Ereignisse:
A_GuiWidth
A_GuiHeight
Quelle: Variablen und Ausdrücke -> Interne Variablen

Sie würden Dir auch nicht helfen, wenn sie verfügbar wären, denn sie beinhalten nicht Position und Abmessungen eines kompletten Gui-Fensters auf dem Bildschirm. Wenn Du Dir die nach dem Gui, Show, ... holen willst, reicht ein

Code: Select all

Gui, %c%:show, ...
WinGetPos, xguiX , xguiY, xguiW, xguiH, %  "ahk_id " . HGui%c%
Wenn Du dem Gui-Fenster vorher ein +LastFound spendierst, brauchst Du den Fenstertitel-Parameter nicht. Die gelieferten Wert sind allerdings nicht skaliert. Sie sollten nur mit der WinMove Anweisung verwendet werden.

effel
Posts: 392
Joined: 16 Jan 2018, 13:34

Re: ListView W-1

Post by effel » 12 Jun 2021, 10:08

hallo just me

ich habe das mit zwei Optionen umgesetzt.

Einmal als 'extra' fix Button Gui, %c%:Add, Button, x+10 gfix hwndHFIX, fix

und mit der Mausrad Funktion. Funktioniert beides.

Gibt es auch sowas wie:
OnMessage(0xzauber, "LinkeMausTasteLosgelassen") ?


Code: Select all

FileCopy, % A_ScriptFullPath, % A_ScriptDir "\save\" A_ScriptName " save " A_Now " .ahk"
#NoEnv
SetBatchLines, -1
FileEncoding, UTF-8
#SingleInstance, force

LOG1 := object()
GuiArr := []
range := "a5:e10" ; Gui#1 startRange
showX := 83 ; Offset erste gui

gosub newc
gosub LoadLog
OnMessage(0x020A, "Mausrad")
return

fix:
;return
GuiPlaces =
loop 20 {
GuiPlaces .= "Gui#" . A_index . ":`t" (LOG1["gui#" . A_index . "_LastMove"]) "`n"
if !LOG1["gui#" . A_index . "_LastMove"]
break
}
                       msgBox,,, % "GuiPlaces:`n" GuiPlaces ;,5
/*
ShowBox := true_
if ShowBox {
msgBox,,, % "Gui#1:`t" (LOG1["gui#" . 1 . "_LastMove"]) "`n"
          . "Gui#2:`t" (LOG1["gui#" . 2 . "_LastMove"]) "`n"
          . "Gui#3:`t" (LOG1["gui#" . 3 . "_LastMove"]) "`n"
          . "Gui#4:`t" (LOG1["gui#" . 4 . "_LastMove"]) "`n"
          . "Gui#5:`t" (LOG1["gui#" . 5 . "_LastMove"]) "`n"
          . "Gui#6__:`t" (LOG1["gui#" . 6 . "_LastMove"])
}
*/
return

fix_TMP:
WinGetPos, xguiX , xguiY, xguiW, xguiH, %  "ahk_id " . HGui%c%
MsgBox,,%A_LineNumber%,% xguiX "`n"
         . xguiY "`n"
         . xguiW "`n"
         . xguiH "`n"
         . ("ahk_id " . HGui%c%),1
if (LOG1["gui#" . c . "_GuiHWND"])
LOG1["gui#" . c . "_LastMove"] := xguiX "|" xguiY
ShowBox := true_
if ShowBox 
msgBox,,, % LOG1["gui#" . c . "_LastMove"],1
return

Mausrad() {
global LOG1
global c
MouseGetPos,,, ID, Control
WinGetPos, xguiX , xguiY, xguiW, xguiH
ShowBox := true_
if ShowBox {
MsgBox,,%A_LineNumber%,% clipBoard := xguiX "`n"
                                    . xguiY "`n"
                                    . xguiW "`n"
                                    . xguiH "`n"
                                    . A_Gui "`n"
                                    . ("ahk_id " . ID),1
}
;if (LOG1["gui#" . A_Gui . "_GuiHWND"])
LOG1["gui#" . c . "_LastMove"] := c " | " xguiX " | " xguiY " | " xguiW " | " xguiH 
if ShowBox {
GuiControl, Hide, hfix
GuiControl, Hide, gfix
Gui %c%:Show, Hide
Sleep, 100
Gui %c%:Show
Sleep, 100
Gui %c%:Show, Hide
Sleep, 100
Gui %c%:Show
Gui %c%:Show, Hide
Sleep, 100
}
Gui %c%:Show
;           msgBox,,, % clipBoard .= LOG1["gui#" . c . "_LastMove"]
}
;###########################################################################################################################
Newc:
++c
Gui, %c%:Submit, nohide
Critical Off  ; Selbst wenn Critical On nie verwendet wurde.
Sleep -1
split := StrSplit(range,":")                          ; ListViewCols
lf := (asc(SubStr(split.2,1,1)) - 96)                 ; ListViewCols
Loop,% lf                                             ; ListViewCols lf = "a2:d7" = d = 4
ListViewCols .= chr(64 + A_Index) "|"                 ; ListViewCols lf = 4
XlApp := ComObjActive("Excel.Application")
For k in XlApp.Range(range) {
        ++aindex
value := k.value
if value is number
{
 values .= Format("{:.2f}", k.value) "|" ; as well ... as
;values .= Round(k.value, 2) "|"         ; as well ... as
}
else 
	values .= k.value "|"
	if (aindex=lf) {
        aindex=
        values .= "`n"
}}
Gui, %c%:New
Gui, %c%:+hwndHGui%c%
Gui, %c%:Default
Gui, %c%:Add, Edit, xm w90 vEDITA,% split.1 " : " split.2 
Gui, %c%:Add, Button, x+10 gNewData, ok
Gui, %c%:Add, Button, x+10 gfix hwndHFIX, fix
Gui, %c%:Add, ListView, xm hwndHLVA,% "#|" ListViewCols
Loop, Parse, Values, `n
Lv_Add("",A_index, StrSplit(A_LoopField,"|")*)
lvc := LV_GetCount()
Loop, % LV_GetCount("Columns")
LV_ModifyCol(A_Index, "AutoHdr")
LVA := LV_EX_CalcViewSize(HLVA,lvc)
LVAH := (lva.h + 30)
LVAW := (lva.w + 30)
if (LVAH>A_ScreenHeight)
LVAH := 600
if (LVAW>A_ScreenWidth)
LVAW := (A_ScreenWidth - 100)
GUIH := (LVAH + 40)
GUIW := (LVAW + 20)
;msgbox,,listViewHoeheBreite,% LVAH "<>" LVAW ,1
GuiControl, %c%:Move, SysListView321, w%LVAW% h%LVAH%
If (c=1)
Gui, %c%:show, x83 y1 w%GUIW% h%GUIH%,% c
else 

; xguiW

{
  AGui_AGuiWidth := (LOG1["gui#" . (c-1) . "_A_GuiWidth"])
  AGui_AGuiX     := (LOG1["gui#" . (c-1) . "_guiX"])
; OffsetRow2    := (LOG1["gui#" . (1) . "_guiH"])   ; 213
  OffsetRow2    := xguiH   ; 213
; msgbox %  OffsetRow2    := (LOG1["gui#" . (1) . "_A_GuiHeigh"])
  showX += AGui_AGuiWidth
  showX += AGui_AGuiX
  showy = (OffsetRow2 ? OffsetRow2 : 500)
if !(showX>(A_ScreenWidth-383)) ; offset zeile zwei
{
Gui, %c%:show, x%showX% y0 w%GUIW% h%GUIH%,% c
}
else
{
if showElseX
showElseX += (AGui_AGuiWidth)
else
showElseX += (83)
showy := (OffsetRow2 ? OffsetRow2 : 500) ; Offset erste gui reihe zwei
Gui, %c%:show, x%showElseX% y%showy% w%GUIW% h%GUIH%,% c
}
}

WinGetPos, xguiX , xguiY, xguiW, xguiH, %  "ahk_id " . HGui%c%
gosub LoadLog
for i, var in LOG1["gui#" . c . "_lva"]
varall .= "gui#" . c . "_LV_EX_" i "`t" (isObject(var) ? "Object" : var) "`n"
for i, var in LOG1
varall .= i "`t" (isObject(var) ? "Object" : var) "`n"
if ShowBox {
MsgBox,,, % varall,1
}
varall:=""
return

LoadLog:
LOG1["gui#" . c . "_A_DefaultGui"] := (A_DefaultGui ? A_DefaultGui : "empty")
LOG1["gui#" . c . "_rows"]         := (lvc ? lvc : "empty")
LOG1["gui#" . c . "_lva"]          := (lva ? lva : "empty")
LOG1["gui#" . c . "_lvah"]         := (lvah ? lvah : "empty")
LOG1["gui#" . c . "_lvaw"]         := (lvaw ? lvaw : "empty")
LOG1["gui#" . c . "_guih"]         := (guih ? guih : "empty")
LOG1["gui#" . c . "_guiw"]         := (guiw ? guiw : "empty")
LOG1["gui#" . c . "_A_GuiHeight"]  := (xguiH ? xguiH : "empty")
LOG1["gui#" . c . "_A_GuiWidth"]   := (xguiW ? xguiW : "empty")
LOG1["gui#" . c . "_A_GuiX"]       := (xguiX ? xguix : "empty")
LOG1["gui#" . c . "_A_GuiY"]       := (xguiY ? xguiY : "empty")
LOG1["gui#" . c . "_GuiHWND"]      := (HGui%c%)
LOG1["gui#" . c . "_hwndHLVA"]     := (HLVA)
;LOG1["gui#" . c . "_Values"]      := ":`n" Values
LOG1["gui#" . c . "_range"]        := range
LOG1["gui#" . c . "_rangeA"]       := split.1
LOG1["gui#" . c . "_rangeb"]       := split.2
;LOG1["gui#" . c . "_XlApp"]        := XlApp
LOG1["gui#" . c . "_cools"]        := (lf ? lf : "empty")
LOG1["gui#" . c . "_coolsCHR"]     := ((chr(64 + lf)) ? (chr(64 + lf)) : "empty")
;GuiArr.Push(LOG1)
Gui, FILL%c%:NEW
Gui, FILL%c%:Add, ListView, w350 r21 hwndHFillLVIDa Grid cBlack BackgroundFFDD99, Key1|Key2|Key3|Key4|Key5|Value
tmp:=FillLV(log1)
Gui, FILL%c%:Show, , GuiStats -> ListView
Gui, FILL%c%:Show, hide
WinGetPos, xguiX , xguiY, xguiW, xguiH, %  "ahk_id " . HGui%c%
jsonFile := (AhkToJSON(LOG1, A_Space))
Gui, JsonFILL%c%:NEW
Gui, JsonFILL%c%:Add, ListView, w350 r21 hwndHFillLVIDb Grid cBlack BackgroundFFDD99, Key1|Key2|Key3|Key4|Key5|Value
Loop, Parse, jsonfile, `n 
RI := LV_Add("", A_Index, A_LoopField)
Loop, % LV_GetCount("Columns")
LV_ModifyCol(A_Index, "AutoHdr", A_Index)
  Gui, JsonFILL%c%:Show, hide, Json -> ListView
; Gui, JsonFILL%c%:Show,     , Json -> ListView
WinGetPos, xguiX , xguiY, xguiW, xguiH, %  "ahk_id " . HGui%c%
fileDelete,% (A_ScriptDir "\" A_Gui " jsonFile.txt")
FileAppend,% jsonFile,% (A_ScriptDir "\" A_Gui " jsonFile.txt")
if fileExist(A_ScriptDir "\" A_Gui " jsonFile.txt")
if ShowBox
run,% (A_ScriptDir "\" A_Gui " jsonFile.txt")
return

NewData:
ListViewCols:=""
Values:=""
Gui, %c%:Submit, nohide
GuiControlGet, range, , EDITA
_range := range
range := strReplace(range,A_Space)
gosub newc
;GuiControlSet, , _range, EDITA
;GuiControl,,EDITA, %w_range%
;MsgBox,,, % range,1
Return

GuiClose:
        reload
GuiEscape:
	Gui, Hide
Return
; ======================================================================================================================
; LV_EX_CalcViewSize - Calculates the approximate width and height required to display a given number of items.
; ======================================================================================================================
LV_EX_CalcViewSize(HLV, Rows := 0) {
   ; LVM_APPROXIMATEVIEWRECT = 0x1040 -> http msdn.microsoft.com /en-us/library/bb774883(v=vs.85).aspx  Broken Link for safety
   SendMessage, 0x1040, % (Rows - 1), 0, , % "ahk_id " . HLV
   Return {W: (ErrorLevel & 0xFFFF), H: (ErrorLevel >> 16) & 0xFFFF}
}
; ======================================================================================================================
AhkToJSON(obj, indent := "") {
   static Doc, JS
   if !Doc {
      Doc := ComObjCreate("htmlfile")
      Doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
      JS := Doc.parentWindow
      ( Doc.documentMode < 9 && JS.execScript() )
   }
   if indent|1 {
      if IsObject( obj ) {
         isArray := true
         for key in obj {
            if IsObject(key)
               throw Exception("Invalid key")
            if !( key = A_Index || isArray := false )
               break
         }
         for k, v in obj
            str .= ( A_Index = 1 ? "" : "," ) . ( isArray ? "" : """" . k . """:" ) . %A_ThisFunc%(v, true)

         Return isArray ? "[" str "]" : "{" str "}"
      }
      else if !(obj*1 = "" || RegExMatch(obj, "^-?0|\s"))
         Return obj
      
      for k, v in [["\", "\\"], [A_Tab, "\t"], ["""", "\"""], ["/", "\/"], ["`n", "\n"], ["`r", "\r"], [Chr(12), "\f"], [Chr(8), "\b"]]
         obj := StrReplace( obj, v[1], v[2] )

      Return """" obj """"
   }
   sObj := %A_ThisFunc%(obj, true)
   Return JS.eval("JSON.stringify(" . sObj . ",'','" . indent . "')")
}

;#################
class CaseSenseList
{
   __New() {
      ObjRawSet(this, "_list_", [])
   }
   
   __Delete() {
      this.SetCapacity("_list_", 0)
      ObjRawSet(this, "_list_", "")
   }
   
   __Set(key, value) {
      for k, v in this._list_ {
         if !(v[1] == key)
            continue
         v[2] := value
         keyExist := true
      } until keyExist
      if !keyExist
         this._list_.Push([key, value])
      Return value
   }
   
   __Get(key) {
      if (key == "_list_")
         Return
      for k, v in this._list_ {
         if (v[1] == key)
            Return v[2]
      }
   }
   
   _NewEnum() {
      Return new this._CustomEnum_(this._list_)
   }
   
   class _CustomEnum_
   {
      __New(list) {
         this.i := 0
         this.list := list
      }
      
      Next(ByRef k, ByRef v := "") {
         if ++this.i <= this.list.Length() {
            k := this.list[this.i, 1]
            v := this.list[this.i, 2]
            Return true
         }
      }
   }
   
   Count() {
      Return this._list_.Length()
   }
   
   Delete(key) {
      for k, v in this._list_
         continue
      until v[1] == key && keyExist := true
      Return keyExist ? this._list_.RemoveAt(k)[2] : ""
   }
   
   HasKey(key) {
      for k, v in this._list_
         if (v[1] == key)
            Return true
      Return false
   }
}
;############################################################################

;FillLV(TestX)

FillLV(Arr, Row := "", Recursive := 0) {
;static VFillLVID
   For K, V In Arr {
      If (Recursive)
         Row .= "`t" . K
      Else
         Row := K
      If IsObject(V)
         FillLV(V, Row, 1)
      Else {
         RI := LV_Add("", StrSplit(Row, "`t")*)
         LV_Modify(RI, "Col6", V)
      }
   }
   Loop, % LV_GetCount("Col")
      LV_ModifyCol(A_Index, "AutoHdr")
;Gui, FillLVID:show ; , w%GUIW% h%GUIH%,% A_GuiX A_Space A_GuiY " gui: " c
}
20210613054834-Monitor-1.jpg
20210613054834-Monitor-1.jpg (293.43 KiB) Viewed 531 times

just me
Posts: 8042
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ListView W-1

Post by just me » 13 Jun 2021, 07:57

Moin,

gut, wenn's funktioniert. Ich habe den Code nur überflogen und bin nicht sicher, was am Ende dabei rauskommen soll.
Gibt es auch sowas wie:

Code: Select all

0xzauber := 0x0202
:arrow: WM_LBUTTONUP

effel
Posts: 392
Joined: 16 Jan 2018, 13:34

Re: ListView W-1

Post by effel » 14 Jun 2021, 15:44

Toller Hinweis, bin gleich damit was am testen.

verstehe nur nicht den Wert der Variable lparam
müssten da nicht zwei Werte drin stehen?

Ich dachte es so verstanden zu haben das dort x und y im Verhältnis zum Element in der aktiven GUI zu holen sind


20210614213804-Monitor-1.jpg
20210614213804-Monitor-1.jpg (19.59 KiB) Viewed 497 times

der Code ist aus dem Zusammenhang und muss so nicht funktionieren...

Code: Select all

WM_MOUSEMOVE_Nachricht(wparam, lparam, msg, hwnd) {
global wm_eventArr
WinGetPos, xguiX , xguiY, xguiW, xguiH ; , %  "ahk_id " . HGui%c%

xwparam := "WM_MOUSEMOVE_Nachricht`n"
         . (wParam=16) ? ("16") 
         : (wParam=8)  ? ("8") 
         : (wParam=4)  ? ("4") 
         : (wParam=2)  ? ("2") 
         : (wParam)

 wm_eventArr[A_TickCount] := A_TickCount ";WM_MOUSEMOVE_Nachricht;" xwparam ";" 
         . "lparam:`t" lparam ";" 
         . "msg:`t" msg ";" 
         . "hwnd:`t" hwnd ";" 
         . ">WM_MOUSEMOVE_Nachricht<"
         . "guiX:`t" xguiX ";" 
         . "guiY:`t" xguiY ";" 
         . "guiW:`t" xguiW ";" 
         . "guiH:`t" xguiH ";" 
         . "ahk_id:`t" (ID) ";" 
         . (A_Gui-1) ";" 
         . c ";" 
         . range ";" 
;---------------------------------------------------
   CoordMode, Mouse, Client
   MouseGetPos,X, Y
   LP := GetlParam(X, Y)
;   FileAppend, lParam: %lParam% ========== LP: %LP%`n,*
ToolTipVar .=   lParam a_tab LP "`n"
Sleep, 100
  ToolTip,% ToolTipVar 
; SetTimer, ToolTipOff, 360
}
;----------------------------------------------------------
GetLParam(LoWord, HiWord ) {
    return (HiWord << 16) | (LoWord & 0xffff)
}

just me
Posts: 8042
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ListView W-1

Post by just me » 15 Jun 2021, 04:57

lParam

The low-order word specifies the x-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.

The high-order word specifies the y-coordinate of the cursor. The coordinate is relative to the upper-left corner of the client area.
In der 'guten alten' 32-Bit-Welt konnte jeder Parameter auch nur 32 Bits umfassen. Für die Nachrichten, die im System für den Austausch von Daten via Post/SendMessage dienen, sind nur zwei Parameter definiert: wParam und lParam. Wenn man die X- und Y-Koordinaten getrennt übermitteln wollte, wären beide Parameter verbraucht. Für die bei WM_LBUTTONUP in wParam zusätzlich übergebenen Informationen wäre kein Platz mehr.

Ein findiger Kopf hat dann aber eine Lösung gefunden:
  • X und Y sind relative Bildschirmkoordinaten.
  • In einem 16-Bit-Wert (WORD.) kann man positive Werte zwischen 0 und 65535 speichern.
  • 65535 ist weit jenseits der maximalen Anzahl der Bildschirmpunkte pro Dimension.
  • In einen 32-Bit-Wert (DWORD) passen zwei 16-Bit-Werte.
  • Damit können beide Koordinaten in einem Parameter übergeben werden.
  • Dazu werden sie wie folgt zusammengesetzt: 0xHHHHLLLL (HHHH = high-order-word, LLLL = low-order word).
Um die Koordinaten aus lParam auszulesen, trennt man sie wieder auf:

Code: Select all

X := lParam & 0xFFFF ; rechte (niederwertige) 16 Bits auslesen
Y := (lParam >> 16) & 0xFFFF ; linke (höherwertige) 16 Bits um 16 Bits nach rechts verschieben und auslesen
Ein Restrisiko bliebe bei nagative X/Y-Werten. Dem kann man so entgehen:

Code: Select all

X := lParam << 48 >> 48
Y := lParam << 32 >> 48
Man schiebt hier den gesünschten Bereich bis zur Vorzeichenstelle (Bit 64) und wieder zurück. AHK füllt dann links mit dem 'Vorzeichen' auf.


Edit:
Warum 48? Weil AHK ganze Zahlen intern als 64-Bit-Werte verwaltet. Die Vorzeichenstelle ist deshalb Bit 64 und nicht, wie zunächst im voranstehenden Text falsch angegeben, 32.

effel
Posts: 392
Joined: 16 Jan 2018, 13:34

Re: ListView W-1

Post by effel » 16 Jun 2021, 11:19

Danke für die Erklärung, ich habe mein erlangtes Wissen einmal hier vertieft

Code: Select all

wm_eventArr := object()


; https://docs.microsoft.com/en-us/windows/win32/inputdev/mouse-input-notifications

++c
Gui, +hwndHGuiA
Gui, Font, s11
Gui, +LastFound 
GUI_W := A_ScreenWidth - 200
GUI_H := A_ScreenHeight - 100
Tab_H := A_ScreenHeight - 500
Tab_W := GUI_W - 200
MaxLV_R := 20
LVA_W := GUI_W -730
LVB_W := GUI_W -30
LVC_W := 550
LVD_W := 550
LVE_W := GUI_W -30
Gui, Add, Tab, w%Tab_W% h%Tab_H%, a|b

; +LV0x00010000 Grid +LV0x20 
;ListView +LV0x00010000 https://www.autohotkey.com/boards/viewtopic.php?p=363948#p363948

Gui, Tab, a
Gui, Add, ListView, w%LVA_W% r%MaxLV_R% +LV0x00010000 Grid +LV0x20 hwndHLVA vLVA Grid cBlack AltSubmit -Readonly BackgroundFFDD99
                  , ATickCount|AThisFunc|wparam|wparam|iparam|iparam|x|y|msg|hwnd|hwnd|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|y|z
ICELVA := New LV_InCellEdit(HLVA, True, True)
ICELVA.OnMessage()
GuiControl , Choose , systabcontrol321 , 1


   RI := Lv_Add("", ,"startup")
   LV_Modify(RI, "Col1", A_TickCount)



;------------------------------------------------------
OnMessage(0x0215, "WM_CAPTURECHANGED")
WM_CAPTURECHANGED(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
sleep, 200
}

OnMessage(0x0203, "WM_LBUTTONDBLCLK")
WM_LBUTTONDBLCLK(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x0201, "WM_LBUTTONDOWN")
WM_LBUTTONDOWN(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x0202, "WM_LBUTTONUP")
WM_LBUTTONUP(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x0209, "WM_MBUTTONDBLCLK")
WM_MBUTTONDBLCLK(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x0207, "WM_MBUTTONDOWN")
WM_MBUTTONDOWN(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x0208, "WM_MBUTTONUP")
WM_MBUTTONUP(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x0021, "WM_MOUSEACTIVATE")
WM_MOUSEACTIVATE(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x02A1, "WM_MOUSEHOVER")
WM_MOUSEHOVER(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
sleep, 999
}

OnMessage(0x020E, "WM_MOUSEHWHEEL")
WM_MOUSEHWHEEL(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
;; sleep, 1
}

OnMessage(0x02A3, "WM_MOUSELEAVE")
WM_MOUSELEAVE(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x0200, "WM_MOUSEMOVE")
WM_MOUSEMOVE(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
sleep, 999
}

OnMessage(0x020A, "WM_MOUSEWHEEL")
WM_MOUSEWHEEL(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
;; sleep, 1
}

OnMessage(0x0084, "WM_NCHITTEST")
WM_NCHITTEST(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x00A3, "WM_NCLBUTTONDBLCLK")
WM_NCLBUTTONDBLCLK(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x00A1, "WM_NCLBUTTONDOWN")
WM_NCLBUTTONDOWN(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x00A2, "WM_NCLBUTTONUP")
WM_NCLBUTTONUP(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x00A9, "WM_NCMBUTTONDBLCLK")
WM_NCMBUTTONDBLCLK(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x00A7, "WM_NCMBUTTONDOWN")
WM_NCMBUTTONDOWN(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x00A8, "WM_NCMBUTTONUP")
WM_NCMBUTTONUP(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x02A0, "WM_NCMOUSEHOVER")
WM_NCMOUSEHOVER(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
sleep, 999
}

OnMessage(0x02A2, "WM_NCMOUSELEAVE")
WM_NCMOUSELEAVE(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x00A0, "WM_NCMOUSEMOVE")
WM_NCMOUSEMOVE(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
sleep, 999
}

OnMessage(0x00A6, "WM_NCRBUTTONDBLCLK")
WM_NCRBUTTONDBLCLK(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x00A4, "WM_NCRBUTTONDOWN")
WM_NCRBUTTONDOWN(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x00A5, "WM_NCRBUTTONUP")
WM_NCRBUTTONUP(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x00AD, "WM_NCXBUTTONDBLCLK")
WM_NCXBUTTONDBLCLK(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x00AB, "WM_NCXBUTTONDOWN")
WM_NCXBUTTONDOWN(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x00AC, "WM_NCXBUTTONUP")
WM_NCXBUTTONUP(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x0206, "WM_RBUTTONDBLCLK")
WM_RBUTTONDBLCLK(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x0204, "WM_RBUTTONDOWN")
WM_RBUTTONDOWN(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x0205, "WM_RBUTTONUP")
WM_RBUTTONUP(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x020D, "WM_XBUTTONDBLCLK")
WM_XBUTTONDBLCLK(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x020B, "WM_XBUTTONDOWN")
WM_XBUTTONDOWN(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

OnMessage(0x020C, "WM_XBUTTONUP")
WM_XBUTTONUP(wparam, lparam, msg, hwnd) {
global AThisFunc, AThisFunc := A_ThisFunc
_all(wparam, lparam, msg, hwnd)
; sleep, 1
}

                          Gui, Show, xCenter yCenter, % ("GuiHwnd: " HGuiA " Label: " LGuiA)




Return



_all(wparam, lparam, msg, hwnd) {
ATickCount := A_TickCount
global AThisFunc
;AThisFunc := A_ThisFunc
WinGetPos, xguiX , xguiY, xguiW, xguiH ;,%  "ahk_id " . HGui%c%
GuiControl, -Redraw, LVA
X := lParam & 0xFFFF ; rechte (niederwertige) 16 Bits auslesen
Y := (lParam >> 16) & 0xFFFF ; linke (höherwertige) 16 Bits um 16 Bits nach rechts verschieben und auslesen
X := lParam << 48 >> 48
Y := lParam << 32 >> 48
RI := Lv_Add("", ATickCount
               , AThisFunc
               , _wparam(wparam)
               , wparam
               , _lParam(lParam)
               , lParam
               , x
               , y
               , _msg(msg)
               , _hwnd(hwnd)
               , hwnd
               , xguiX
               , xguiY
               , xguiW
               , xguiH 
               , A_TimeSinceThisHotkey
               , A_TimeSincePriorHotkey)

LV_Modify(RI, "+Focus")
;LV_Modify(RI, "+Select")
Ri := LV_GetCount()
  Loop, % LV_GetCount()
  LV_Modify((A_Index), "-Select")
    Loop, % LV_GetCount("Columns")
    LV_ModifyCol(A_Index, "AutoHdr")
LV_Modify(LV_GetCount(), "+Select")
LV_Modify(LV_GetCount(), "Vis")
GuiControl, +Redraw, LVA
}

_wparam(wparam) {
xwparam := (wParam=16) ? ("Die mittlere Maustaste ist unten!") 
         : (wParam=8)  ? ("STRG-Down!") 
         : (wParam=4)  ? ("Shift-Down!") 
         : (wParam=2)  ? ("RMouse-Down!") 
         : ((isObject(wParam) ? "Object" : "0x" . Format("{:X}", wParam)))
Return xwparam 
}
_lParam(lParam) {
xlParam := ((isObject(lParam) ? "Object" : "0x" . Format("{:X}", lParam)))
Return xlParam
}
___iparam(iparam) {
return iparam
X := lParam & 0xFFFF ; rechte (niederwertige) 16 Bits auslesen
Y := (lParam >> 16) & 0xFFFF ; linke (höherwertige) 16 Bits um 16 Bits nach rechts verschieben und auslesen
X := lParam << 48 >> 48
Y := lParam << 32 >> 48
   RI := Lv_Add("",,A_ThisFunc)
   LV_Modify(RI, "Col1", A_TickCount)
   LV_Modify(RI, "Col3", tmp)
   LV_Modify(RI, "Col4", x, y)
  Loop, % LV_GetCount("Columns")
  LV_ModifyCol(A_Index, "AutoHdr VIS")
LV_Modify(RI, "+Focus")
;LV_Modify(RI, "+Select")
Ri := LV_GetCount()
LV_Modify(Ri, "Vis")
LV_Modify(RI, "+Select")

;LV_Modify((RI-1), "-Select")
LV_Modify((RI-1), "-Select")

GuiControl, +Redraw, LVA
Return ToolTipVar .= x  ";" y ";" iparam
}
_msg(msg) {
Return (isObject(msg) ? "Object" : msg)
}
_hwnd(hwnd) {
Return (isObject(hwnd) ? "Object" : "0x" . Format("{:X}", hwnd))
}


xiparam(thisMsg, wparam, lparam, msg, hwnd) {
X := lParam & 0xFFFF ; rechte (niederwertige) 16 Bits auslesen
Y := (lParam >> 16) & 0xFFFF ; linke (höherwertige) 16 Bits um 16 Bits nach rechts verschieben und auslesen
X := lParam << 48 >> 48
Y := lParam << 32 >> 48
Return ToolTipVar .=    "x:`t" x  "`n" "y:`t" y "`n" StrReplace(wm_eventVar,";","`n")
}

Unbenannt.png
Unbenannt.png (86.75 KiB) Viewed 450 times

just me
Posts: 8042
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: ListView W-1

Post by just me » 17 Jun 2021, 05:03

Moin,

das ist eine gelungene Darstellung des Nachrichtenverkehrs, der (fast) allein durch die Maus ausgelöst wird.

Ich habe da noch ein paar Anmerkungen:
  1. Funktionsschachtelung:
    Die Ausgaben werden mit der Funktion _all() gesteuert. Der werden immer alle 4 Nachrichtenparameter übergeben. Für die aufrufende Funktion nutzt Du aber eine globale Variable. Ich denke, die kannst Du getrost als zusätzlichen Parameter übergeben:

    Code: Select all

    WM_LBUTTONDOWN(wparam, lparam, msg, hwnd) {
    _all(A_ThisFunc, wparam, lparam, msg, hwnd)
    ; sleep, 1
    }
    ...
    _all(AThisFunc, wparam, lparam, msg, hwnd) {
    ATickCount := A_TickCount
    ;global AThisFunc
    ;AThisFunc := A_ThisFunc
    ...
    
  2. Code: Select all

    Loop, % LV_GetCount()
    	LV_Modify((A_Index), "-Select")
    
    Das kann mit wachsendem Inhalt schon mal länger dauern. Man kann es durch

    Code: Select all

    LV_Modify(0, "-Select")
    ersetzen.
  3. Code: Select all

    isObject(wParam)
    Die Übergabe von Objekten, die AHK als solche erkennen kann, ist bei Nachrichten zumindest eine seltene Ausnahme. Im Zusammenhang mit Mausnachrichten kommt das nicht vor.
  4. Code: Select all

    _wparam(wparam)
    Die in wParam übergebenen Werte für zusätzlich gedrückte Tasten werden als Kombination von Werten übergeben. Der Wert 0x000C (0x0004 + 0x0008) bedeutet:
    Die Tasten Ctrl und Shift sind gedrückt.
Und in jedem Fall solltest Du dem Skript den Kopf

Code: Select all

#NoEnv
SetBatchLines, -1
spendieren. Schon die Verarbeitung der WM_MOUSEMOVE Nachrichten ist recht anstrengend.

Post Reply

Return to “Ich brauche Hilfe”