Gui动态添加编辑ListView控件行.ahk

; 【更多例子详见链接】https://www.autohotkey.com/boards/viewtopic.php?f=6&t=55019
#NoEnv
SetBatchLines -1
SetWorkingDir %A_ScriptDir%

; 另一个链接是界面漂亮,但是有BUG。
; https://www.autohotkey.com/boards/viewtopic.php?p=304129#p304129

gui, add, listview, w310 vLV1 gLVEvents BackgroundWhite Grid, Id|A|B|C|D

loop, 5
LV_ModifyCol(a_index, 55)	;columns change columns width

loop, 4
LV_Add("", a_index)		;add rows

gui, add, button, xm gAdd, Add
gui, add, button, x+5 gEdit, Edit
gui, add, text, x+5, "选择:双击行编辑它们!"

gui, show
return

LVEvents:	;_____________ LVEvents ________________

if (A_GuiEvent = "DoubleClick")
LV_AddEditRow(A_Gui, A_GuiControl, "Modify")

return

Edit:		;____________ Edit _______________

LV_AddEditRow(A_Gui, "LV1", "Modify")

return

Add:		;____________ Add _______________

LV_AddEditRow(A_Gui, "LV1", "Add")

return


guiclose:	;_____________ gui close _______________
exitapp


LV_AddEditRow(GuiWnd, LVCtrl, Status, Optns := "")	;_______________ Add/Edit ListView Controls Rows - v1.0 (Function) ___________________
{

;Local	;uncomment this line if you use AutoHotKey v1.1.27+
  ;Force all variables in this function to be "Local" vars (with no exceptions)
  ;"Force-local" mode (only supported on AutoHotKey v1.1.27+)
  ;this function was tested in AutoHotKey 1.1.23.05

  ;Local TempControlId	;this line was disabled because otherwise it would switch the function mode from "assume-Local" to "assume-Global" (makes all variables global by default)

Static ControlHwndId := [], CtrlType := [], CtrlHwnd := []		;declare the variable as an object and remember its values between function calls 

Static GuiWindow, LVControl, FocusedRow, TotalCols, Options, GuiHwnd	;"Static" variables, remember values between function calls 

if (Status = "GetVar")
return, (%LVCtrl%)		;return the values of static variables from this function

if (Status = "GetObject")	;return the values of static Objects from this function
return, %GuiWnd%[LVCtrl]

GuiWindow := GuiWnd
LVControl := LVCtrl

Options := Optns.Clone()
;"Clone()", Returns a shallow (not always a 100% clone???) copy of the object.
;"Clone()" creates a new object from the object referenced by "Optns" variable!
;then, "Options" variable will reference that newly created/cloned object!

Gui, %GuiWindow%:Default	;forces Built-in ListView Functions to operate upon the indicated gui window
Gui, ListView, % LVControl	;forces built-in ListView functions to operate upon the indicated Listview Control (the control must belong to the indicated gui window above)

FocusedRow := LV_GetNext(0, "Focused")
;Search for the focused row ("0", the search starts from row number 1!
;there is never more than one focused row in the entire list, and sometimes there is none at all!

  if (Status = "Modify" and FocusedRow = 0)
  {
  msgbox, 8240, Warning!, No row is selected! Please, select a row to be modified!
  ;"8240" sum of 8192 and 48 (8192 for "Task Modal" option \ 48 for Icon Exclamation + sound)
  ;"52" sum of 4 and 48 (4 for "yes - no" options \ 48 for Icon Exclamation + sound)

  gui, LVAddEditRow:Destroy

  return
  }

TotalCols := LV_GetCount("Col")		;the function returns the number of columns in the control

gui, LVAddEditRow:Default
gui, destroy
Gui +HwndGuiHwnd

  loop, % TotalCols
  {
  Gui, %GuiWindow%:Default			;forces Built-in ListView Functions to operate upon the indicated gui window
  LV_GetText(TempHeader, 0, a_index)		;"0" is the columns header row / "a_index" is the column number

  if (Status = "Modify")
  LV_GetText(TempText, FocusedRow, a_index)	;"a_index" is the column number

  gui, LVAddEditRow:Default

    TempIndex := a_index
    loop
    {
      if (Options["BeforeCell" TempIndex "Ctrl" a_index "Type"] = "")
      break
      else
      {
      gui, add, % Options["BeforeCell" TempIndex "Ctrl" a_index "Type"], % "+HwndTempControlId " Options["BeforeCell" TempIndex "Ctrl" a_index "Options"], % Options["BeforeCell" TempIndex "Ctrl" a_index "Text"]

      TempKey := Options["BeforeCell" TempIndex "Ctrl" a_index "Hwnd"]
      CtrlHwnd[TempKey] := TempControlId
      }
    }

  gui, add, text, % Options["Cell" a_index "HeaderOptions"], % TempHeader

    ;Ternary operator, ( ? = if ) and ( : = else )

  ControlType := ControlOption := ControlText := ""	;blank\empty values

  ControlType := CtrlType[a_index] := Options["Cell" a_index "Type"] != "" ? Options["Cell" a_index "Type"] : "Edit"

    if (ControlType = "Checkbox")
    {
    ControlOption := Status = "Add" ? "" : "Checked" TempText
    }
    else if (ControlType = "DateTime")
    {
    TempText := TempText = "" ? "None" : RegExReplace(TempText, "\D")	;"\D" means any non-digit (remove any non-digit characters)
    ControlOption := Status = "Add" ? "" : "Choose" TempText
    }
    else if (ControlType = "ListBox" or ControlType = "DropDownList" or ControlType = "DDL")
    {
      if (Status = "Modify")
      {
      TempIndex := a_index
      TempList := Options["Cell" TempIndex "Text"], Options["Cell" TempIndex "Text"] := ""

        loop, parse, TempList, |
        {
        if (A_LoopField == "")		;if blank\empty (== is case-sensitive)
        continue			;Skips the rest of the current loop iteration and begins a new one. Valid inside any kind of loop.

        TempString := A_LoopField

          loop, parse, TempText, |
          {
            if ("S" TempString == "S" A_LoopField)		;"==" is case-sensitive, "S" forces "string" comprisons and avoids "number" comparisons!
            {
            TempString .= "|"
            break
            }

          }

        Options["Cell" TempIndex "Text"] .= TempString "|"
        }
      }
    }
    else if (ControlType != "Edit" and ControlType != "ComboBox")
    {
    if (ControlType = "MonthCal")
    TempText := RegExReplace(TempText, "\Q/")	;remove any "/" character

    if (Status = "Modify")
    ControlText := TempText, Options["Cell" a_index "Text"] := ""
    }

  gui, add, % ControlType, % "+HwndTempControlId " Options["Cell" a_index "Options"] " " ControlOption, % Options["Cell" a_index "Text"] ControlText

    if (Status = "Modify")
    {
    if (ControlType = "Edit" or ControlType = "ComboBox")
    ControlSetText, , % TempText, % "ahk_id" TempControlId		;"ControlSetText" prevents "EOL" (End of LIne Translation), no "`n" is translated to "`r`n"
    }

  ControlHwndId[a_index] := TempControlId		;the variable must be declared as an object first ("ControlHwndId := []")
  
  TempKey := Options["Cell" a_index "Hwnd"]
  CtrlHwnd[TempKey] := TempControlId

    TempIndex := a_index
    loop
    {
      if (Options["AfterCell" TempIndex "Ctrl" a_index "Type"] = "")
      break
      else
      {
      if (a_index = "1" and Status = "Modify" and Options["AfterCell" TempIndex "Ctrl" a_index "Type"] = "UpDown")
      Options["AfterCell" TempIndex "Ctrl" a_index "Text"] := RegExReplace(TempText, "\.|,")		;Regex removes thousands separator (. or ,)

      gui, add, % Options["AfterCell" TempIndex "Ctrl" a_index "Type"], % "+HwndTempControlId " Options["AfterCell" TempIndex "Ctrl" a_index "Options"], % Options["AfterCell" TempIndex "Ctrl" a_index "Text"]

      TempKey := Options["AfterCell" TempIndex "Ctrl" a_index "Hwnd"]
      CtrlHwnd[TempKey] := TempControlId
      }
    }

  }

TempText := ""	 ;make variable blank (free memory)

if (Status = "Modify")
GuiCaption := ButtonCaption := "Modify"
else
GuiCaption := ButtonCaption := "Add"

gui, add, button, xm gLVAddEditRowLabel Default, % ButtonCaption

  if (Status = "Modify")
  {
  gui, add, button, x+5 gLVAddEditRowLabel , Add
  gui, add, button, x+5 gLVAddEditRowLabel , Delete
  }

gui, add, button, x+5 gLVAddEditRowGuiClose, Cancel

gui, show, , % GuiCaption

return

LVAddEditRowLabel:	;_________ Function Label __________

Gui, %GuiWindow%:Default	;forces Built-in ListView Functions to operate upon the indicated gui window
Gui, ListView, % LVControl	;forces built-in ListView functions to operate upon the indicated Listview Control (the control must belong to the indicated gui window above)

  if (a_guicontrol = "Delete")
  {
  LV_Delete(FocusedRow)
  FocusedRow := LV_GetNext(0, "Focused")		;Search for the focused row ("0", the search starts from row number 1!
  }

  if (a_guicontrol = "Add" or a_guicontrol = "Modify")
  {
    if (a_guicontrol = "Add")
    {
    FocusedRow := LV_Insert(Options["NewRowIndex"] = "" ? LV_GetCount() + 1 : Options["NewRowIndex"], Options["NewRowOptions"])
    ;The function adds a new row to the specified index position (if the ListView control does not have the "Sort" or "SortDesc" style)
    ;The function returns the new row number, which is not necessarily the specified index position if the ListView has the "Sort" or "SortDesc" style.
    ;Ternary operator, (? = if) and (: = else)
    ;if Options["NewRowIndex"] is blank\empty, the new row will be inserted to the end of the listview control, "LV_GetCount() + 1"
    ;for some reason, the Options["NewRowOptions"] prevents Autohotkey from crashing if Options["NewRowIndex"] is blank/empty and the ListView control contains "Sort" or "SortDesc" options
    }

    if (a_guicontrol = "Modify")
    {
    LV_Modify(FocusedRow, Options["RowOptions"])
    }

    loop, % TotalCols
    {
    if (CtrlType[a_index] = "Edit" or CtrlType[a_index] = "ComboBox")
    ControlGetText, TempText, , % "ahk_id" ControlHwndId[a_index]		;"ControlGetText" prevents EOL "End of line translation", no "`r`n" is translated to "`n"
    else
    GuiControlGet, TempText, LVAddEditRow:, % ControlHwndId[a_index]

      if (CtrlType[a_index] = "DateTime")
      {
      if (TempText != "")
      FormatTime, TempText, % TempText, yyyy-MM-dd/HH:mm:ss		;"HH" 24-hour format (00 – 23)
      }
      else if (CtrlType[a_index] = "MonthCal")
      {
        if (TempText != "")
        {
          Loop, Parse, TempText, -
          {
          TempText := a_index = 1 ? "" : TempText

          FormatTime, TempTime, % A_LoopField, yyyy/MM/dd		;"MonthCal" does not retrieve  "HH24MISS" time portion , retrieves only "YYYYMMDD" Date

          TempText .= TempTime "-"
          }

        TempText := RegExReplace(TempText, "-$")	;remove the last "-" character at the end of the string
        }
      }

    LV_Modify(FocusedRow, "Col" a_index, TempText)
    }
  }

LV_Modify(0, "-Select")		;Deselect all rows

LV_Modify(FocusedRow, "Focus Select Vis")
;"vis", Ensures that the specified row is completely visible by scrolling the ListView, if necessary.
;"Vis", has an effect only for "LV_Modify()" function! (does not work with "LV_Add()" function!)
;"Focus", Sets keyboard focus to the row / "Select", highlight the row

LVAddEditRowGuiClose:	;_______ LVAddEditRow Gui Close _______
LVAddEditRowGuiEscape:

Gui, %GuiWindow%:Default	;forces Built-in ListView Functions to operate upon the indicated gui window
Gui, ListView, % LVControl	;forces built-in ListView functions to operate upon the indicated Listview Control (the control must belong to the indicated gui window above)

GuiControl, Focus, % A_DefaultListView		;"A_DefaultListView" supported from [v1.1.23+]

if (Options["GoSub"] != "")	;if not blank/empty
GoSub, % Options["GoSub"]	;"GoTo" is not allowed inside functions, only "GoSub" is!

TempText := "", ControlHwndId := [], CtrlType := [], CtrlHwnd := [], Options := []	 ;make variable blank (free memory)

gui, LVAddEditRow:Destroy	;by destroying the gui window, "a_guicontrol" will be made blank\empty!

return
}

 

声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。