以下的脚本作者为:蜜獾哥

编辑框指定行写入.ahk

; 以记事本为例
lineIndex := 2
insertText := "xxxxxxxx`n"

ControlGet, hwnd, Hwnd,, edit1, ahk_class Notepad

; 获取光标位置
charIndex := DllCall("user32\SendMessage", "Ptr", hwnd, "uint", EM_LINEINDEX := 0x00BB, "int", lineIndex, "int", 0, "int")
; 改变光标位置
DllCall("user32\SendMessage", "Ptr", hwnd, "uint", EM_SETSEL := 0x00B1, "int", charIndex, "int", charIndex, "int")

Control, EditPaste, %insertText%, edit1, ahk_class Notepad

 

【增强控制示例】ListBox增删DllCall.ahk

Gui, Destroy
Gui, Add, ListBox, w300 HWNDhlb,1|2|3|4|5|6
Gui, Show

; 获取listbox总数
Count:= DllCall("User32.dll\SendMessage", "Ptr", HLB, "UInt", LB_GETCOUNT := 0x018B, "Ptr", 0, "Ptr", 0, "Ptr") 
MsgBox % Count

; 插入listbox项
Index := 3, VarSetCapacity(String,128), StrPut("指定位置插入一项", &String, "utf-16")
MsgBox % DllCall("User32\SendMessage", "Ptr", HLB, "UInt", LB_INSERTSTRING := 0x0181, "UInt", Index-1, "Ptr", &String)+1

; 新增(追加)listbox项
VarSetCapacity(String,128),StrPut("新增一项", &String, "utf-16")
MsgBox % DllCall("User32\SendMessage", "Ptr", HLB, "UInt", LB_ADDSTRING := 0x0180, "Ptr", 0, "Ptr", &String)+1

; 删除listbox指定下标项
Index:=3
MsgBox % DllCall("User32\SendMessage", "Ptr", HLB, "UInt", LB_DELETESTRING := 0x0182, "UInt", Index-1, "Ptr", 0, "Ptr")

; 删除listbox指定内容
VarSetCapacity(String,128),StrPut("新增一项", &String, "utf-16")
Index:= DllCall("User32\SendMessage", "Ptr", HLB, "UInt", LB_FINDSTRINGEXACT := 0x01A2, "UInt", -1, "Ptr", &String)+1
MsgBox % DllCall("User32\SendMessage", "Ptr", HLB, "UInt", LB_DELETESTRING := 0x0182, "UInt", Index-1, "Ptr", 0, "Ptr")

; 删除listbox所有项
MsgBox % DllCall("User32\SendMessage", "Ptr", HLB, "UInt", LB_RESETCONTENT := 0x0184, "Ptr", 0, "Ptr", 0, "Ptr")

 

【增强控制类】Listbox简单列表控件.ahk

Gui,Destroy
Gui,Add,ListBox,HWNDhlb r20 w200 Choose2,item1|item2|item|item3|item4|item5
Gui,Show,w300 h300 x500 y300
Gui,+OwnDialogs
MsgBox % "选择[item]项,返回当前行号:`n" CListBox.SelectString(hlb,"item")
MsgBox % "追加一项到列表,返回总行数:`n" (Index:=CListBox.Add(hlb,"我是新增项"))
MsgBox % "选择刚刚追加项,返回当前行号:`n" CListBox.SetCurSel(hlb, Index)
MsgBox % "在第三行处插入一项,返回行号成功反之:`n" CListBox.Insert(hlb,"我是插入项",3)
MsgBox % "修改第三行内容,返回1成功反之:`n" CListBox.Modify(hlb,3,"我是修改项")
MsgBox % "获取第五行内容:`n" CListBox.GetText(hlb,5)
MsgBox % "获取字符[item5]项在列表中的行号:`n" CListBox.GetItemPos(hlb, "item5")
MsgBox % "获取高亮行行号:`n" CListBox.GetCurrentSel(hlb)
MsgBox % "获取列表总行数:`n" CListBox.GetCount(hlb)
MsgBox % "选择所有列表项内容以指定符号分隔:`n[ " CListBox.GetAllItem(hlb,",") " ]"
MsgBox % "删除第二行,返回1成功反之:`n" CListBox.Delete(hlb,2)
MsgBox % "删除[item]项,返回1成功反之:`n" CListBox.DeleteItem(hlb,"item")
MsgBox % "清空列表:`n" CListBox.DeleteAll(hlb)
Return

GuiClose:
  ExitApp
Return

Class CListBox {
  /*
    新增(追加)listbox项
    HWND:ListBox控件句柄
    Text:要追加字符
    成功返回总行数否则返回false
  */

  Add(HWND,Text){
    Static LB_ADDSTRING := 0x0180
    VarSetCapacity(String,StrPut(Text,"utf-16")*4),StrPut(Text, &String, "utf-16")
    Index:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_ADDSTRING, "Ptr", 0, "Ptr", &String)+1
    Count:=this.GetCount(HWND),this.SetCurSel(HWND, Count)
    Return Count=Index?Count:False
  }
  /*
    指定位置插入listbox项
    HWND:ListBox控件句柄
    Pos:指定插入的行号,Pos=0时追加插入
    Text:要追加字符
    成功返回行号否则返回false
  */

  Insert(HWND,Text,Pos:=1){
    Static LB_INSERTSTRING := 0x0181
    VarSetCapacity(String,StrPut(Text,"utf-16")*4),StrPut(Text, &String, "utf-16")
    Index:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_INSERTSTRING, "UInt", Pos-1, "Ptr", &String)+1
    if (Index>=Pos)
      this.SetCurSel(HWND, Index)
    Return Index>=Pos?Index:False
  }
  /*
    获取listbox总行数
    成功返回总行数
  */

  GetCount(HWND){
    Static LB_GETCOUNT := 0x018B
    Return DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", LB_GETCOUNT, "Ptr", 0, "Ptr", 0, "Ptr") 
  }
  /*
    删除listbox指定行
    HWND:ListBox控件句柄
    Pos:指定删除的行号
    成功返回True否则返回false
  */

  Delete(HWND,Pos){
    Static LB_DELETESTRING := 0x0182
    i:=this.GetCount(HWND)
    Index:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_DELETESTRING, "UInt", Pos-1, "Ptr", 0, "Ptr")
    Count:=this.GetCount(HWND)
    Return Index=Count&&Count<i?True:False
  }

  ; 删除listbox所有项
  DeleteAll(HWND){
    Static LB_RESETCONTENT := 0x0184
    Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_RESETCONTENT, "Ptr", 0, "Ptr", 0, "Ptr")
  }

  ; 删除listbox指定条目,成功返回True否则返回false
  DeleteItem(HWND,Text){
    Pos:=this.GetItemPos(HWND, Text),Index:=this.Delete(HWND,Pos)
    Return Index?True:False
  }
  /*
    修改指定行的字符串,Pos=0时视为追加新字符串
    HWND:ListBox控件句柄
    Pos:要修改的指定行
    Text:要替换的新字符
    成功返回True否则返回false
  */

  Modify(HWND,Pos,Text){
    Status:=this.Delete(HWND,Pos)
    Index:=this.Insert(HWND,Text,Pos)
    Return Index=Pos?True:False
  }
  /*
    获取listbox指定行的字符串
    HWND:ListBox控件句柄
    Pos:要修改的指定行
    成功返回字符串反之为空
  */

  GetText(HWND,Pos){
    Static LB_GETTEXTLEN := 0x018A
    Static LB_GETTEXT := 0x0189
    len:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_GETTEXTLEN, "UInt", Pos-1, "Ptr", 0, "Ptr")
    VarSetCapacity(Text, Len << !!A_IsUnicode, 0)
    DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_GETTEXT, "UInt", Pos-1, "Ptr", &Text)
    Return StrGet(&Text, Len)
  }
  /*
    获取listbox全部字符串项
    HWND:ListBox控件句柄
    separator:指定分割符
    成功返回字符串反之为空
  */

  GetAllItem(HWND,separator:="|"){
    ControlGet, GETALLTEXT, List , Count, , ahk_id%HWND%
    Return StrReplace(Trim(GETALLTEXT,"`r`n"),"`n",separator)
  }
  /*
    根据指定字符串项获取在listbox中的位置(在第几行)
    HWND:ListBox控件句柄
    Text:要匹配的字符
    成功返回位置(行号)
  */

  GetItemPos(HWND, Text) {
    Static LB_FINDSTRINGEXACT := 0x01A2
    VarSetCapacity(String,StrPut(Text,"utf-16")*4),StrPut(Text, &String, "utf-16")
    Index:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_FINDSTRINGEXACT, "UInt", -1, "Ptr", &String)+1
    Count:=this.GetCount(HWND)
    Return Count&&Index?Index:False
  }

  ;返回选中的高亮项行号(单选)
  GetCurrentSel(HWND) {
    Static LB_GETCURSEL := 0x0188
    Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_GETCURSEL, "UInt", 0, "Ptr")+1
  }

  ;选中listbox列表中的指定条目,返回行号
  SelectString(HWND, Text) {
    ;;Static LB_SELECTSTRING := 0x018C
    ;;VarSetCapacity(String,StrPut(Text,"utf-16")*4),StrPut(Text, &String, "utf-16")
    ;;Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_SELECTSTRING, "UInt", -1, "Ptr", &String)+1
    if Index:=this.GetItemPos(HWND, Text){
      Return this.SetCurSel(HWND, Index)
    }
  }

  ;选中listbox列表中的指定行
  SetCurSel(HWND, Index){
    Static LB_SETCURSEL := 0x0186
    Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_SETCURSEL, "UInt", Index-1, "Ptr", 0, "Ptr")+1
  }

  ;设置listbox行高
  SetItemHeight(HWND, Height) {
    Static LB_SETITEMHEIGHT := 0x01A0
    
    Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_SETITEMHEIGHT, "UInt", -1, "UInt", Height, "Ptr")+1
  }

  ;获取listbox行高
  GetItemHeight(HWND) {
    Static LB_GETITEMHEIGHT := 0x01A1
    Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_GETITEMHEIGHT, "UInt", 0, "UInt", 0, "Ptr")
  }
}

 

SendMessage操作Combobox&DropDownList控件示例.ahk

Gui,6:Destroy
Gui,6:+AlwaysOnTop
;如果ListBox控件加了AltSubmit属性,触发点击事件时v标签接收的只有行号非其内容。
;设置一个g标签GuiControl_Gui接收点击事件,v标签SetCB承载控件的内容与标识
Gui,6:Add,ComboBox, h150 w250 gGuiControl_Gui vSetCB HWNDhcb,item1|item2|item|item3|item4|item5
;Gui,6:Add,DropDownList, h150 w250 gGuiControl_Gui vSetCB HWNDhcb,item1|item2|item|item3|item4|item5
Gui,6:Add,Button,xm y+10 gGuiControl_Gui voption_0,展开
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_1,选择[item]项
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_2,追加一行
Gui,6:Add,Button,xm y+10 gGuiControl_Gui voption_3,修改第4行内容
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_4,获取第5行内容
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_5,第3行处插入1行
Gui,6:Add,Button,xm y+10 gGuiControl_Gui voption_6,获取[item5]在列表中行号
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_7,获取高亮选中行行号
Gui,6:Add,Button,xm y+10 gGuiControl_Gui voption_8,获取列表总行数
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_9,获取所有列表项内容
Gui,6:Add,Button,xm y+10 gGuiControl_Gui voption_10,删除第2行
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_11,删除[item]项
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_12,清空列表
Gui,6:Add,Button,xm y+10 gGuiControl_Gui voption_13,增加水印提示文字`n控件处于空选时显示
Gui,6:Show,AutoSize,ComboBox或DropDownList示例
Return

GuiControl_Gui:
  Switch A_GuiControl
  {
    Case "option_0":
      CB_DDL.Show(hcb,True)
    Case "option_1":
      Gui,+OwnDialogs
      MsgBox % "选择[item]项,返回当前行号:`n" (Index:=CB_DDL.SelectString(hcb,"item"))
      CB_DDL.Show(hcb,True),CB_DDL.SetCursel(hcb,Index)
    Case "option_2":
      Gui,+OwnDialogs
      MsgBox % "追加一项到列表,返回总行数:`n" (Index:=CB_DDL.Add(hcb,"我是新增项"))
      CB_DDL.Show(hcb,True)
    Case "option_3":
      Gui,+OwnDialogs
      MsgBox % "修改第4行内容,返回1成功反之:`n" CB_DDL.Modify(hcb,4,"我是修改项")
      CB_DDL.Show(hcb,True)
    Case "option_4":
      Gui,+OwnDialogs
      MsgBox % "获取第五行内容:`n" CB_DDL.GetText(hcb,5)
      CB_DDL.Show(hcb,True),CB_DDL.SetCursel(hcb,5)
    Case "option_5":
      Gui,+OwnDialogs
      MsgBox % "在第三行处插入一项,返回行号成功反之:`n" CB_DDL.Insert(hcb,"我是插入项",3)
      CB_DDL.Show(hcb,True)
    Case "option_6":
      Gui,+OwnDialogs
      MsgBox % "获取字符[item5]项在列表中的行号:`n" (Index:=CB_DDL.GetItemPos(hcb, "item5"))
      CB_DDL.Show(hcb,True),CB_DDL.SetCursel(hcb,Index)
    Case "option_7":
      Gui,+OwnDialogs
      MsgBox % "获取高亮行行号:`n" CB_DDL.GetCurrentSel(hcb)
      CB_DDL.Show(hcb,True)
    Case "option_8":
      Gui,+OwnDialogs
      MsgBox % "获取列表总行数:`n" CB_DDL.GetCount(hcb)
      CB_DDL.Show(hcb,True)
    Case "option_9":
      Gui,+OwnDialogs
      MsgBox % "选择所有列表项内容以指定符号分隔:`n[ " CB_DDL.GetAllItem(hcb,",") " ]"
      CB_DDL.Show(hcb,True)
    Case "option_10":
      Gui,+OwnDialogs
      MsgBox % "删除第二行,返回1成功反之:`n" CB_DDL.Delete(hcb,2)
      CB_DDL.Show(hcb,True)
    Case "option_11":
      Gui,+OwnDialogs
      MsgBox % "删除[item]项,返回1成功反之:`n" CB_DDL.DeleteItem(hcb,"item")
      CB_DDL.Show(hcb,True)
    Case "option_12":
      Gui,+OwnDialogs
      MsgBox % "清空列表:`n" CB_DDL.DeleteAll(hcb)
      CB_DDL.Show(hcb,True)
    Case "option_13":
      CB_DDL.SelectString(hcb, "")
      CB_DDL.SetCuebanner(hcb, "CB或DDL下拉框")
    Case "SetCB":
      Gui,6:Submit,NoHide
      /*
        如果不加==>Gui,6:Submit,NoHide就需要在用GuiControlGet获取ComboBox或DropDownList选择项内容
        GuiControlGet, SetCB ,, SetCB, Text
        如果ComboBox或DropDownList控件加了AltSubmit属性,获取值就是选择项的行号
      */
      Gui,+OwnDialogs
      MsgBox % SetCB
  }
Return

6GuiClose:
  ExitApp
Return

Class CB_DDL
{
  /*
    新增(追加)ComboBox或DropDownList项
    HWND:ComboBox或DropDownList控件句柄
    Text:要追加字符
    成功返回总行数否则返回false
  */
  add(HWND,Text){
    Static CB_ADDSTRING:=0x143

    VarSetCapacity(String,StrPut(Text,"utf-16")*4),StrPut(Text, &String, "utf-16")
    Index:=DllCall("User32\SendMessage", "UInt", hWnd, "UInt", CB_ADDSTRING, "UInt", 0, "Ptr", &String)+1
    Count:=this.GetCount(HWND),this.SetCurSel(HWND, Count)
    Return Count=Index?Count:False
  }

  /*
    指定位置插入ComboBox或DropDownList项
    HWND:ComboBox或DropDownList控件句柄
    Pos:指定插入的行号,Pos=0时追加插入
    Text:要追加字符
    成功返回行号否则返回false
  */
  Insert(HWND,Text,Pos:=1){
    Static CB_INSERTSTRING:=0x14A

    VarSetCapacity(String,StrPut(Text,"utf-16")*4),StrPut(Text, &String, "utf-16")
    Index:=DllCall("User32\SendMessage", "UInt", hWnd, "UInt", CB_INSERTSTRING, "UInt", Pos-1, "Ptr", &String)+1
    if (Index>=Pos)
      this.SetCurSel(HWND, Index)
    Return Index>=Pos?Index:False
  }

  /*
    删除ComboBox或DropDownList指定行
    HWND:ComboBox或DropDownList控件句柄
    Pos:指定删除的行号
    成功返回True否则返回false
  */
  Delete(HWND,Pos){
    Static CB_DELETESTRING := 0x144

    i:=this.GetCount(HWND)
    Index:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", CB_DELETESTRING, "UInt", Pos-1, "Ptr", 0, "Ptr")
    Count:=this.GetCount(HWND)
    Return Index=Count&&Count<i?True:False
  }

  ;显示ComboBox或DropDownList下拉列表
  Show(HWND,flag:=True){
    Static CB_SHOWDROPDOWN:=0x14F

    Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", CB_SHOWDROPDOWN, "Ptr", flag, "Ptr", 0, "Ptr")
  }

  ; 删除ComboBox或DropDownList所有项
  DeleteAll(HWND){
    Static CB_RESETCONTENT := 0x14B

    Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", CB_RESETCONTENT, "Ptr", 0, "Ptr", 0, "Ptr")
  }

  ; 删除ComboBox或DropDownList指定条目,成功返回True否则返回false
  DeleteItem(HWND,Text){
    Pos:=this.GetItemPos(HWND, Text),Index:=this.Delete(HWND,Pos)

    Return Index?True:False
  }

  /*
    获取ComboBox或DropDownList指定行的字符串
    HWND:ComboBox或DropDownList控件句柄
    Pos:要修改的指定行
    成功返回字符串反之为空
  */
  GetText(HWND,Pos){
    Static CB_GETLBTEXTLEN := 0x149
    Static CB_GETLBTEXT := 0x148

    len:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", CB_GETLBTEXTLEN, "UInt", Pos-1, "Ptr", 0, "Ptr")
    VarSetCapacity(Text, Len << !!A_IsUnicode, 0)
    DllCall("User32\SendMessage", "Ptr", HWND, "UInt", CB_GETLBTEXT, "UInt", Pos-1, "Ptr", &Text)
    Return StrGet(&Text, Len)
  }

  /*
    获取ComboBox或DropDownList全部字符串项
    HWND:ComboBox或DropDownList控件句柄
    separator:指定分割符
    成功返回字符串反之为空
  */
  GetAllItem(HWND,separator:="|"){
    ControlGet, GETALLTEXT, List , Count, , ahk_id%HWND%
    Return StrReplace(Trim(GETALLTEXT,"`r`n"),"`n",separator)
  }

  /*
    根据指定字符串项获取在ComboBox或DropDownList中的位置(在第几行)
    HWND:ComboBox或DropDownList控件句柄
    Text:要匹配的字符
    成功返回位置(行号)
  */
  GetItemPos(HWND, Text) {
    Static CB_FINDSTRINGEXACT := 0x158

    VarSetCapacity(String,StrPut(Text,"utf-16")*4),StrPut(Text, &String, "utf-16")
    Index:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", CB_FINDSTRINGEXACT, "UInt", -1, "Ptr", &String)+1
    Count:=this.GetCount(HWND)
    Return Count&&Index?Index:False
  }

  ;选中ComboBox或DropDownList列表中的指定条目,返回行号
  SelectString(HWND, Text) {
    if Index:=this.GetItemPos(HWND, Text){
      Return this.SetCurSel(HWND, Index)
    }Else{
      ControlSetText , , %Text%, ahk_id%HWND%
      Return False
    }
  }

  /*
    修改指定行的字符串,Pos=0时视为追加新字符串
    HWND:ComboBox或DropDownList控件句柄
    Pos:要修改的指定行
    Text:要替换的新字符
    成功返回True否则返回false
  */
  Modify(HWND,Pos,Text){
    Status:=this.Delete(HWND,Pos)
    Index:=this.Insert(HWND,Text,Pos)

    Return Index=Pos?True:False
  }

  /*
    获取ComboBox或DropDownList总行数
    成功返回总行数
  */
  GetCount(HWND){
    Static CB_GETCOUNT := 0x146

    Return DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", CB_GETCOUNT, "Ptr", 0, "Ptr", 0, "Ptr") 
  }

  ;返回选中的高亮项行号(单选)
  GetCurrentSel(HWND){
    Static CB_GETCURSEL:=0x147

    Return DllCall("User32\SendMessage", "UInt", hWnd, "UInt", CB_GETCURSEL, "UInt", 0, "UInt", 0)+1
  }

  ;选中ComboBox或DropDownList列表中的指定行
  SetCursel(HWND,Pos){
    Static CB_SETCURSEL:=0x14E

    Return DllCall("User32\SendMessage", "UInt", hWnd, "UInt", CB_SETCURSEL, "UInt", Pos-1, "UInt", 0)+1
  }

  ;设置Combobox或DropDownList框水印提示文字
  SetCuebanner(HWND, string){
    static CB_SETCUEBANNER := 0x1703
    return DllCall("user32\SendMessage", "ptr", HWND, "uint", CB_SETCUEBANNER, "int", 0, "str", string, "int")
  }
}

 

SendMessage操作Edit控件示例更新.ahk

; F1::Control, EditPaste, 可以在指定位置粘贴字符串内容, Edit1, ahk_id %htest%

string=
(join`r`n LTrim
赵客缦胡缨,吴钩霜雪明。
银鞍照白马,飒沓如流星。
十步杀一人,千里不留行。
事了拂衣去,深藏身与名。
闲过信陵饮,脱剑膝前横。
将炙啖朱亥,持觞劝侯嬴。
三杯吐然诺,五岳倒为轻。
眼花耳热后,意气素霓生。
救赵挥金槌,邯郸先震惊。
)
Gui,Destroy
Gui,+HWNDhtest +AlwaysOnTop
Gui,Font,s12
Gui,Add,Edit,w280 r6 HWNDhedit,% string
Gui,Add,Button,xm y+10 gOptionGuiEvent vOption_1,追加一行
Gui,Add,Button,x+10 yp gOptionGuiEvent vOption_2,获取总行数
Gui,Add,Button,x+10 yp gOptionGuiEvent vOption_3,获取光标所在行号
Gui,Add,Button,xm y+10 gOptionGuiEvent vOption_4,获取光标所在行文本字符
Gui,Add,Button,x+10 yp gOptionGuiEvent vOption_5,滚到最后一行
Gui,Add,Button,xm y+10 gOptionGuiEvent vOption_6,获取第5行文本字符
Gui,Add,Button,x+10 yp gOptionGuiEvent vOption_7,光标位置
Gui,Add,Button,xm y+10 gOptionGuiEvent vOption_8,定位至第2行
Gui,Add,Button,x+10 yp gOptionGuiEvent vOption_9,第4行插入一行
Gui,Show,AutoSize,SendMessage操作Edit控件示例
CEdit.FocusToLine(hedit,1,True)
Return

GuiClose:
  ExitApp
Return

OptionGuiEvent:
  Switch A_GuiControl
  {
    Case "Option_1":
      CEdit.Append(hedit, "我是追加的字符")
      CEdit.ScrollCaret(hedit)
    Case "Option_2":
      Count:=CEdit.GetLineCount(hedit)
      Gui,+OwnDialogs
      MsgBox % Count
    Case "Option_3":
      Gui,+OwnDialogs
      MsgBox % CEdit.GetCaretLine(hedit)
    Case "Option_4":
      Gui,+OwnDialogs
      MsgBox % CEdit.GetLineChar(hedit)
    Case "Option_5":
      CEdit.ScrollCaret(hedit)
    Case "Option_6":
      Gui,+OwnDialogs
      MsgBox % CEdit.GetLineChar(hedit,5)
    Case "Option_7":
      Sel:=CEdit.GetSel(hedit)
      Gui,+OwnDialogs
      MsgBox % Sel.start "-" Sel.end
    Case "Option_8":
      CEdit.FocusToLine(hedit,2)
    Case "Option_9":
      CEdit.InsertChar(hedit,"我是插入字符`r`n",4,False)
  }
Return
  
Class CEdit
{
  ;获取Edit控件内指定行文本内容
  GetLineChar(HWND, LineNumber=-1){
    static EM_GETLINE=196

    if (LineNumber = -1)
      LineNumber := this.GetCaretLine(HWND)
    len := this.LineLength(HWND, LineNumber)
    ifEqual, len, 0, return

    VarSetCapacity(Text, len*4,0), NumPut(len = 1 ? 2 : len, Text)
    DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_GETLINE, "Ptr", LineNumber-1, "Ptr", &Text, "Ptr")
    VarSetCapacity(Text, -1)
    return len = 1 ? SubStr(Text, 1, -1) : Text
  }

  LineLength(HWND, LineNumber) {
    static EM_LINELENGTH=193

    Return DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_LINELENGTH, "Ptr", LineNumber, "Ptr", 0, "Ptr")
  }

  ;根据字符在edit控件的位置获取字符坐标
  GetPosFromChar(HWND,CharPos,ByRef X,ByRef Y){
    Static EM_POSFROMCHAR:=0xD6

    p:=DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_POSFROMCHAR, "Ptr", CharPos, "Ptr", 0, "Ptr")
    X:=(p & 0xFFFF)<<48>>48
    ;-- LOWORD of result and converted from UShort to Short
    Y:=(p>>16)<<48>>48
    ;-- HIWORD of result and converted from UShort to Short
  }

  ;定位到edit控件指定行位置
  FocusToLine(HWND,LineNumber,toend:=True){
    Static EM_LINEINDEX := 0xBB
    Static EM_LINESCROLL:=0xB6
    Static EM_SCROLLCARET := 0x00B7
    static EM_GETSCROLLPOS:=1245,EM_SETSCROLLPOS:=1246

    VarSetCapacity(POINT, 8, 0)
    Pos:=DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_LINEINDEX, "Ptr", LineNumber-1, "Ptr", 0, "Ptr")
    len := this.LineLength(HWND, LineNumber)
    this.SetSel(HWND, toend?Pos+1+len:Pos+1, toend?Pos+1+len:Pos+1)
    DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_SCROLLCARET, "Ptr", 0, "Ptr", 0, "Ptr")
    this.GetPosFromChar(HWND,toend?Pos+1+len:Pos+1,xpos,ypos)
    ControlFocus,,ahk_id %HWND%
    DllCall("User32.dll\SetCaretPos", "Int", xpos, "Int", ypos)

    Return toend?Pos+1+len:Pos+1
  }

  ;获取光标在edit控件中的第几行
  GetCaretLine(HWND){
    Static EM_LINEINDEX := 0xBB
    Static EM_EXLINEFROMCHAR := 0x0436
    Static EM_LINEFROMCHAR = 0xC9

    Pos:=DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_LINEINDEX, "Ptr", -1, "Ptr", 0, "Ptr")
    Return DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_LINEFROMCHAR, "Ptr", Pos, "Ptr", 0, "Ptr")+1
  }

  ;有edit控件第几行插入字符,插入前面还是后面取决于toend
  InsertChar(HWND,Text,LineNumber,toend=True){
    Static EM_REPLACESEL := 0xC2

    CharPos:=this.FocusToLine(HWND,LineNumber,toend)
    DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_REPLACESEL, "Ptr",1, "Ptr", &text, "Ptr")
  }

  ;向edit控件追加字符,newline追加时是否换行
  Append(HWND, text,newline:=True){
    Static EM_REPLACESEL:=0xC2
    Static WM_VSCROLL:=0x115

    this.SetSel(HWND, -2, -1),Text:=newline?"`r`n" Trim(Text,"`r`n"):Text
    DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_REPLACESEL, "Ptr",1, "Ptr", &text, "Ptr")
    DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", WM_VSCROLL, "Ptr", 7, "Ptr", 0, "Ptr")
    pos:=this.GetSel(HWND)
    this.GetPosFromChar(HWND,pos.End,xpos,ypos)
    ControlFocus,,ahk_id %HWND%
    DllCall("User32.dll\SetCaretPos", "Int", xpos, "Int", ypos)
  }

  ;获取edit控件中内容总行数
  GetLineCount(HWND){
    Static EM_GETLINECOUNT := 0xBA

    Return DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_GETLINECOUNT, "Ptr", 0, "Ptr", 0, "Ptr")
  }


  ;设置edit控件内字符与控件边框的左右间距
  SetMargins(Hwnd, Left := "", Right := "") {
    Static EM_SETMARGINS = 0x00D3
    Set := 0 + (Left <> "") + ((Right <> "") * 2)
    Margins := (Left <> "" ? Left & 0xFFFF : 0) + (Right <> "" ? (Right & 0xFFFF) << 16 : 0)
    Return DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_SETMARGINS, "Ptr", Set, "Ptr", Margins, "Ptr")
  }

  ;滚动编辑控件的内容到最后一行直到插入符号可见,NoHighlight去高亮显示
  ScrollCaret(HWND,NoHighlight:=True) { ; Scrolls the caret into view.
    Static EM_SCROLLCARET := 0x00B7

    Count:=this.GetLineCount(HWND)
    this.FocusToLine(HWND,this.GetLineChar(HWND, Count)<>""?Count:Count-1,True)
    DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_SCROLLCARET, "Ptr", 0, "Ptr", 0, "Ptr")
    Return True
  }

  ;获取edit控件鼠标选中字符的首尾位置
  GetSel(HWND) {
    Static EM_GETSEL = 0x00B0
    start:=0,End:=0

    DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_GETSEL, "Ptr", &start, "Ptr", &end, "Ptr")
    Return {Start: NumGet(start, 0, "UInt"), End: NumGet(end, 0, "UInt")}
  }

  ;选中edit控件中指定位置的字符
  SetSel(HWND, Start, End) {
    Static EM_SETSEL:=0x00B1

    Return DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", EM_SETSEL, "Ptr", Start - 1, "Ptr", End - 1, "Ptr")
  }

  ;当edit控件内容为空时设置水印提示字符,Edit框为单行时显示
  SetCueBanner(Hwnd, string, hideonfocus := true){
    static EM_SETCUEBANNER := 0x1501
    return DllCall("user32\SendMessage", "ptr", Hwnd, "uint", EM_SETCUEBANNER, "int", hideonfocus, "str", string, "int")
  }
}

 

SendMessage操作Listbox控件示例.ahk

Gui,6:Destroy
Gui,6:+AlwaysOnTop
;如果ListBox控件加了AltSubmit属性,触发点击事件时v标签接收的只有行号非其内容。
;设置一个g标签GuiControl_Gui接收点击事件,v标签SetLB承载控件的内容与标识
Gui,6:Add,ListBox, h150 w250 gGuiControl_Gui vSetLB HWNDhlb,item1|item2|item|item3|item4|item5
Gui,6:Add,Button,xm y+10 gGuiControl_Gui voption_0 Disabled,展开
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_1,选择[item]项
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_2,追加一行
Gui,6:Add,Button,xm y+10 gGuiControl_Gui voption_3,修改第4行内容
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_4,获取第5行内容
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_5,第3行处插入1行
Gui,6:Add,Button,xm y+10 gGuiControl_Gui voption_6,获取[item5]在列表中行号
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_7,获取高亮选中行行号
Gui,6:Add,Button,xm y+10 gGuiControl_Gui voption_8,获取列表总行数
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_9,获取所有列表项内容
Gui,6:Add,Button,xm y+10 gGuiControl_Gui voption_10,删除第2行
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_11,删除[item]项
Gui,6:Add,Button,x+10 yp gGuiControl_Gui voption_12,清空列表
Gui,6:Show,AutoSize,ListBox示例
MsgBox % CListBox.CalcIdealWidth(hlb)
Return

GuiControl_Gui:
  Switch A_GuiControl
  {
    Case "option_0":

    Case "option_1":
      Gui,+OwnDialogs
      MsgBox % "选择[item]项,返回当前行号:`n" CListBox.SelectString(hlb,"item")

    Case "option_2":
      Gui,+OwnDialogs
      MsgBox % "追加一项到列表,返回总行数:`n" (Index:=CListBox.Add(hlb,"我是新增项"))

    Case "option_3":
      Gui,+OwnDialogs
      MsgBox % "修改第4行内容,返回1成功反之:`n" CListBox.Modify(hlb,4,"我是修改项")
    Case "option_4":
      Gui,+OwnDialogs
      MsgBox % "获取第五行内容:`n" CListBox.GetText(hlb,5)
    Case "option_5":
      Gui,+OwnDialogs
      MsgBox % "在第三行处插入一项,返回行号成功反之:`n" CListBox.Insert(hlb,"我是插入项",3)
    Case "option_6":
      Gui,+OwnDialogs
      MsgBox % "获取字符[item5]项在列表中的行号:`n" CListBox.GetItemPos(hlb, "item5")

    Case "option_7":
      Gui,+OwnDialogs
      MsgBox % "获取高亮行行号:`n" CListBox.GetCurrentSel(hlb)

    Case "option_8":
      Gui,+OwnDialogs
      MsgBox % "获取列表总行数:`n" CListBox.GetCount(hlb)

    Case "option_9":
      Gui,+OwnDialogs
      MsgBox % "选择所有列表项内容以指定符号分隔:`n[ " CListBox.GetAllItem(hlb,",") " ]"
      CListBox.SelectString(hlb,"")
    Case "option_10":
      Gui,+OwnDialogs
      MsgBox % "删除第二行,返回1成功反之:`n" CListBox.Delete(hlb,2)

    Case "option_11":
      Gui,+OwnDialogs
      MsgBox % "删除[item]项,返回1成功反之:`n" CListBox.DeleteItem(hlb,"item")

    Case "option_12":
      Gui,+OwnDialogs
      MsgBox % "清空列表:`n" CListBox.DeleteAll(hlb)
    Case "SetLB":
      Gui,6:Submit,NoHide
      /*
        如果不加==>Gui,6:Submit,NoHide就需要在用GuiControlGet获取listbox选择项内容
        GuiControlGet, SetLB ,, SetLB, ListBox
        如果ListBox控件加了AltSubmit属性,获取值就是选择项的行号
      */
      Gui,+OwnDialogs
      MsgBox % SetLB
  }
Return

6GuiClose:
  ExitApp
Return

Class CListBox
{
  /*
    新增(追加)listbox项
    HWND:ListBox控件句柄
    Text:要追加字符
    成功返回总行数否则返回false
  */
  Add(HWND,Text){
    Static LB_ADDSTRING := 0x0180

    VarSetCapacity(String,StrPut(Text,"utf-16")*4),StrPut(Text, &String, "utf-16")
    Index:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_ADDSTRING, "Ptr", 0, "Ptr", &String)+1
    Count:=this.GetCount(HWND),this.SetCurSel(HWND, Count)
    Return Count=Index?Count:False
  }

  /*
    指定位置插入listbox项
    HWND:ListBox控件句柄
    Pos:指定插入的行号,Pos=0时追加插入
    Text:要追加字符
    成功返回行号否则返回false
  */
  Insert(HWND,Text,Pos:=1){
    Static LB_INSERTSTRING := 0x0181

    VarSetCapacity(String,StrPut(Text,"utf-16")*4),StrPut(Text, &String, "utf-16")
    Index:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_INSERTSTRING, "UInt", Pos-1, "Ptr", &String)+1
    if (Index>=Pos)
      this.SetCurSel(HWND, Index)
    Return Index>=Pos?Index:False
  }

  /*
    获取listbox总行数
    成功返回总行数
  */
  GetCount(HWND){
    Static LB_GETCOUNT := 0x018B

    Return DllCall("User32.dll\SendMessage", "Ptr", HWND, "UInt", LB_GETCOUNT, "Ptr", 0, "Ptr", 0, "Ptr") 
  }

  /*
    删除listbox指定行
    HWND:ListBox控件句柄
    Pos:指定删除的行号
    成功返回True否则返回false
  */
  Delete(HWND,Pos){
    Static LB_DELETESTRING := 0x0182

    i:=this.GetCount(HWND)
    Index:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_DELETESTRING, "UInt", Pos-1, "Ptr", 0, "Ptr")
    Count:=this.GetCount(HWND)
    Return Index=Count&&Count<i?True:False
  }

  ; 删除listbox所有项
  DeleteAll(HWND){
    Static LB_RESETCONTENT := 0x0184

    Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_RESETCONTENT, "Ptr", 0, "Ptr", 0, "Ptr")
  }

  ; 删除listbox指定条目,成功返回True否则返回false
  DeleteItem(HWND,Text){
    Pos:=this.GetItemPos(HWND, Text),Index:=this.Delete(HWND,Pos)

    Return Index?True:False
  }

  /*
    修改指定行的字符串,Pos=0时视为追加新字符串
    HWND:ListBox控件句柄
    Pos:要修改的指定行
    Text:要替换的新字符
    成功返回True否则返回false
  */
  Modify(HWND,Pos,Text){
    Status:=this.Delete(HWND,Pos)
    Index:=this.Insert(HWND,Text,Pos)

    Return Index=Pos?True:False
  }

  /*
    获取listbox指定行的字符串
    HWND:ListBox控件句柄
    Pos:要修改的指定行
    成功返回字符串反之为空
  */
  GetText(HWND,Pos){
    Static LB_GETTEXTLEN := 0x018A
    Static LB_GETTEXT := 0x0189

    len:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_GETTEXTLEN, "UInt", Pos-1, "Ptr", 0, "Ptr")
    VarSetCapacity(Text, Len << !!A_IsUnicode, 0)
    DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_GETTEXT, "UInt", Pos-1, "Ptr", &Text)
    Return StrGet(&Text, Len)
  }

  /*
    获取listbox全部字符串项
    HWND:ListBox控件句柄
    separator:指定分割符
    成功返回字符串反之为空
  */
  GetAllItem(HWND,separator:="|"){
    ControlGet, GETALLTEXT, List , Count, , ahk_id%HWND%
    Return StrReplace(Trim(GETALLTEXT,"`r`n"),"`n",separator)
  }

  /*
    根据指定字符串项获取在listbox中的位置(在第几行)
    HWND:ListBox控件句柄
    Text:要匹配的字符
    成功返回位置(行号)
  */
  GetItemPos(HWND, Text) {
    Static LB_FINDSTRINGEXACT := 0x01A2

    VarSetCapacity(String,StrPut(Text,"utf-16")*4),StrPut(Text, &String, "utf-16")
    Index:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_FINDSTRINGEXACT, "UInt", -1, "Ptr", &String)+1
    Count:=this.GetCount(HWND)
    Return Count&&Index?Index:False
  }

  ;返回选中的高亮项行号(单选)
  GetCurrentSel(HWND) {
    Static LB_GETCURSEL := 0x0188

    Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_GETCURSEL, "UInt", 0, "Ptr")+1
  }

  ;选中listbox列表中的指定条目,返回行号
  SelectString(HWND, Text) {
    ;;Static LB_SELECTSTRING := 0x018C
    ;;VarSetCapacity(String,StrPut(Text,"utf-16")*4),StrPut(Text, &String, "utf-16")
    ;;Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_SELECTSTRING, "UInt", -1, "Ptr", &String)+1

    if Index:=this.GetItemPos(HWND, Text){
      Return this.SetCurSel(HWND, Index)
    }Else
      Return False
  }

  SelectAllItem(HWND){
    Static LB_SETSEL := 0x0185
    PostMessage, 0x0185, 1, -1, , ahk_id%HWND%
    Return DllCall("User32\PostMessage", "Ptr", HWND, "UInt", LB_SETSEL, "UInt", 1, "UInt",-1)+1
  }

  ;选中listbox列表中的指定行
  SetCurSel(HWND, Index){
    Static LB_SETCURSEL := 0x0186

    Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_SETCURSEL, "UInt", Index-1, "Ptr", 0, "Ptr")+1
  }

  ;设置listbox行高
  SetItemHeight(HWND, Height) {
    Static LB_SETITEMHEIGHT := 0x01A0
    
    Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_SETITEMHEIGHT, "UInt", -1, "UInt", Height, "Ptr")+1
  }

  ;获取listbox行高
  GetItemHeight(HWND) {
    Static LB_GETITEMHEIGHT := 0x01A1

    Return DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_GETITEMHEIGHT, "UInt", 0, "UInt", 0, "Ptr")
  }

  ;根据listbox项获取单行真实宽度
  CalcIdealWidth(HWND){
    Static WM_GETFONT := 0x0031
    hFont:=DllCall("User32\SendMessage", "Ptr", HWND, "UInt", WM_GETFONT, "UInt", 0, "UInt", 0, "Ptr")
    if !hFont
      Return False
    ControlGet, Content, List, , , ahk_id %HWND%
    Items := StrSplit(Content, "`n")
    HDC := DllCall("User32.dll\GetDC", "Ptr", HWND, "UPtr")
    DllCall("Gdi32.dll\SelectObject", "Ptr", HWND, "Ptr", HFONT)
    VarSetCapacity(SIZE, 8, 0)
    For Each, Item In Items
    {
      DllCall("Gdi32.dll\GetTextExtentPoint32", "Ptr", HDC, "Ptr", &Item, "Int", StrLen(Item), "UIntP", Width)
      If (Width > MaxW)
        MaxW := Width
    }
    DllCall("User32.dll\ReleaseDC", "Ptr", HLB, "Ptr", HDC)

    Return MaxW + 8
  }

  ;获取listbox单行行高与宽度
  GetItemRect(HWND){
    Static LB_GETITEMRECT := 0x0198

    VarSetCapacity(RECT, 16, 0)
    DllCall("User32\SendMessage", "Ptr", HWND, "UInt", LB_GETITEMRECT, "Ptr", 0, "Ptr", &RECT, "Ptr")
    ItemWidth := NumGet(RECT, 8, "Int") - NumGet(RECT, 0, "Int")
    ItemHeight := NumGet(RECT, 12, "Int") - NumGet(RECT, 4, "Int")
    Return {Width:ItemWidth,Height:ItemHeight}
  }

}

 

SendMessage操作ListView控件示例.ahk

#NoEnv
; #Warn
SendMode Input
SetWorkingDir %A_ScriptDir%
#SingleInstance Force
OnMessage(0x404, "AHK_NOTIFYICON")
Gosub OpenSetting
Menu,Tray,Tip,单击或双击托盘图标打开窗口
Return

OpenSetting:
  Gui,Test:Destroy
  Gui,Test:Default
  Gui,Test:+Resize
  SysGet, CXVSCROLL, 2 
  LVWidth:=LVWidth?LVWidth:350,LVHeight:=LVHeight?LVHeight:150  ;设定listview尺寸
  ,CGuiHeight:=0,CGuiWidth:=0  ;初始化
  Gui,Test:Add, ListView,w%LVWidth% h%LVHeight% AltSubmit Grid +E0x10 -LV0x10 -Multi NoSortHdr -WantF2 0x8 LV0x40  LV0x800 LV0x80 gControl_Gui vSetHLV HWNDHLV, 编号|内容
  LV_ModifyCol(1,LVWidth*0.25),LV_ModifyCol(2,LVWidth*0.75-CXVSCROLL*(A_ScreenDPI/96) " Center"),Count:=1
  Loop,15
    LV_Add("",A_Index,Count++ "-1")
  LV:=New ExtLV(HLV)
  Gui,Test:Show,AutoSize,SendMessage操作ListView
return

TestGuiSize:
  if A_Cursor In SizeNESW,SizeNS,SizeNWSE,SizeWE
  {
    GuiControlGet,CGSize,Test:Pos,SetHLV
    if (!CGuiHeight&&!CGuiWidth&&CGSizeW=LVWidth) {
      Gui, Test:+MinSize%A_GuiWidth%x%A_GuiHeight%
    }else{
      GuiControlGet,CGSize,Test:Pos,SetHLV
      GuiControl,Test:Move,SetHLV,% "w" CGSizeW+A_GuiWidth-CGuiWidth " h" CGSizeH+A_GuiHeight-CGuiHeight
      LV_ModifyCol(1,(CGSizeW+A_GuiWidth-CGuiWidth)*0.25),LV_ModifyCol(2,(CGSizeW+A_GuiWidth-CGuiWidth)*0.75-CXVSCROLL*(A_ScreenDPI/96))
    }
    CGuiHeight:=A_GuiHeight,CGuiWidth:=A_GuiWidth,LVWidth:=CGSizeW,LVHeight:=CGSizeH
  }
return

Control_Gui:
  Gui,Test:Submit,NoHide
  Switch A_GuiControl
  {
    Case "SetHLV":
      LV.GetItemHitPos(lRows,lColumn)  ;获取点击行列号
      SubItemText:=LV.GetSubItemText(lRows,lColumn)
      ColumnWidth:=LV.GetColumnWidth(lColumn)
      ToolTipBox.ToolTip("行:" lRows "`n列:" lColumn "`n单元格内容:" SubItemText "`n列宽:" ColumnWidth,,,6,{auto_color:True})
  }
Return

TestGuiClose:
  Gui,Test:Destroy
Return

AHK_NOTIFYICON(wParam, lParam, uMsg, hWnd){
  if (lParam = 0x201||lParam = 0x203) {
    Gosub OpenSetting
  }
}

Class ExtLV
{
  __New(HWND){
    this.HWND:=HWND
    Return this
  }

  ;全选所有行,flag=1全选,反之
  SelectAll(flag:=True,HWND:=0){
    Static LVM_SETITEMSTATE := 0x1000 + 43

    HLV:=HWND?HWND:this.HWND?this.HWND:0
    VarSetCapacity(LVITEM, 4*15, 0)
    NumPut(0x00000008, LVITEM, 4*0) ;LVIF_STATE
    NumPut(flag?0x00000002:0x00000000, LVITEM, 4*3) ;state
    NumPut(0x0002, LVITEM, 4*4) ;LVIS_SELECTED
    DllCall("User32\SendMessage", "Ptr", HLV, "UInt", LVM_SETITEMSTATE, "Ptr", -1, "Ptr", &LVITEM)
    ControlFocus, SysListview321
  }

  ;获取目标ListView选择的行列位置信息
  GetItemHitPos(ByRef Row, ByRef Column,HWND:=0,Xpos:=-1, Ypos:=-1) {
    Static LVM_SUBITEMHITTEST := 0x1039
    Static LVHT_ONITEM := 0x0000000E

    HLV:=HWND?HWND:this.HWND?this.HWND:0
    if !HLV
      Return {}
    VarSetCapacity(LVHTI, 24, 0)
    if (Xpos = -1) || (Ypos = -1){
      DllCall("User32.dll\GetCursorPos", "Ptr", &LVHTI)
      DllCall("User32.dll\ScreenToClient", "Ptr", HLV, "Ptr", &LVHTI)
    }Else{
      NumPut(Xpos, LVHTI, 0, "Int")
      NumPut(Ypos, LVHTI, 4, "Int")
    }
    r:=DllCall("User32\SendMessage", "Ptr", HLV, "UInt", LVM_SUBITEMHITTEST, "Ptr", 0, "Ptr", &LVHTI)
    Row:= r > 0x7FFFFFFF ? 0 : r + 1
    Column:=(NumGet(LVHTI, 8, "UInt") & LVHT_ONITEM) ? NumGet(LVHTI, 16, "Int") + 1 : 0
    Return {Row:Row,Column:Column}
  }

  ;获取目标ListView指定行列单元格内容
  GetSubItemText(Row, Column :=1,HWND:=0, MaxChars := 257){
    Static LVM_GETITEMTEXTW:=0x1073,LVM_GETITEMTEXTA:=0x102D
    Static LVM_GETITEMTEXT := A_IsUnicode ? LVM_GETITEMTEXTW : LVM_GETITEMTEXTA
    Static OffText := 16 + A_PtrSize
    Static OffTextMax := OffText + A_PtrSize

    HLV:=HWND?HWND:this.HWND?this.HWND:0
    if !HLV
      Return ""
    VarSetCapacity(ItemText, MaxChars << !!A_IsUnicode, 0)
    VarSetCapacity(LVITEM, 48 + (A_PtrSize * 3), 0)
    NumPut(0, LVITEM, 0, "UInt"), NumPut(Row - 1, LVITEM, 4, "Int")
    , NumPut(Column - 1, LVITEM, 8, "Int")
    NumPut(&ItemText, LVITEM, OffText, "Ptr")
    NumPut(MaxChars, LVITEM, OffTextMax, "Int")
    DllCall("User32\SendMessage", "Ptr", HLV, "UInt", LVM_GETITEMTEXT, "Ptr", Row - 1, "Ptr", &LVITEM)
    VarSetCapacity(ItemText, -1)
    Return ItemText
  }

  ;获取目标ListView指定行状态
  GetItemState(Row,HWND:=0) {
    Static LVM_GETITEMSTATE:= 0x102C
    Static LVIS := {Cut: 0x04, DropHilited: 0x08, Focused: 0x01, Selected: 0x02, Checked: 0x2000}

    HLV:=HWND?HWND:this.HWND?this.HWND:0
    States :=DllCall("User32\SendMessage", "Ptr", HLV, "UInt", LVM_GETITEMSTATE, "Ptr", Row - 1, "Ptr", 0xFFFF, "Ptr")
    Result := {}
    For Key, Value In LVIS
      Result[Key] := States & Value
    Return Result
  }

  ;修改listview指定单元格内容
  SetText(Text, Row, Col:=1,HWND:=0) {
    Static LVM_SETITEMTEXTA := 0x102E, LVM_SETITEMTEXTW := 0x1074
    Static LVM_SETITEMTEXT := A_IsUnicode ? LVM_SETITEMTEXTW : LVM_SETITEMTEXTA

    HLV:=HWND?HWND:this.HWND?this.HWND:0
    VarSetCapacity(LVITEM, 48 + (A_PtrSize * 3), 0)
    NumPut(0, LVITEM, 0, "UInt"), NumPut(Row - 1, LVITEM, 4, "Int"), NumPut(Col - 1, LVITEM, 8, "Int")
    NumPut(&Text, LVITEM, 16 + A_PtrSize, "UPtr") ; <<<<< changed "Int" to "UPtr"
    Return DllCall("User32\SendMessage", "Ptr", HLV, "UInt", LVM_SETITEMTEXT, "Ptr", Row - 1, "Ptr", &LVITEM, "UInt")
  }

  ;获取目标ListView中的下一项
  GetNextItem(Row,HWND:=0) {
    Static LVM_GETNEXTITEM := 0x100C

    HLV:=HWND?HWND:this.HWND?this.HWND:0
    Return DllCall("User32\SendMessage", "Ptr", HLV, "UInt", LVM_GETNEXTITEM, "Ptr", Row, "Ptr", 0)
  }

  ;设置listview背景图片
  SetBackImage(ImgPath,HWND:=0) {
    Static LVM_SETBKIMAGEA := 0x1044
    Static OSVERSION := DllCall("Kernel32.dll\GetVersion", "UInt") & 0xFF
    Static LVS_EX_DOUBLEBUFFER:=0x00010000
    Static LVBKIF_TYPE_WATERMARK:=0x10000000

    HLV:=HWND?HWND:this.HWND?this.HWND:0
    if !HLV
      Return False
    HBITMAP:=LoadPicture(ImgPath,"GDI+")
    ; 设置扩展样式LVS_EX_DOUBLEBUFFER以避免绘图问题
    this.SetExtendedStyle(LVS_EX_DOUBLEBUFFER, LVS_EX_DOUBLEBUFFER,HLV) 
    If (HBITMAP) && (OSVERSION >= 6)
      LVBKIF_TYPE_WATERMARK |= 0x20000000 ; LVBKIF_FLAG_ALPHABLEND
    LVBKIMAGESize :=  A_PtrSize = 8 ? 40 : 24
    VarSetCapacity(LVBKIMAGE, LVBKIMAGESize, 0)
    NumPut(LVBKIF_TYPE_WATERMARK, LVBKIMAGE, 0, "UInt")
    NumPut(HBITMAP, LVBKIMAGE, A_PtrSize, "UPtr")
    Return DllCall("User32\SendMessage", "Ptr", HLV, "UInt", LVM_SETBKIMAGEA, "Ptr", 0, "Ptr", &LVBKIMAGE)
  }

  GetExtendedStyle(HWND:=0) {
    Static LVM_GETEXTENDEDLISTVIEWSTYLE := 0x1037

    HLV:=HWND?HWND:this.HWND?this.HWND:0
    Return DllCall("User32\SendMessage", "Ptr", HLV, "UInt", LVM_GETEXTENDEDLISTVIEWSTYLE, "Ptr", 0, "Ptr", 0, "Ptr")
  }

  SetExtendedStyle(StyleMsk, Styles,HWND:=0) {
    Static LVM_SETEXTENDEDLISTVIEWSTYLE := 0x1036

    HLV:=HWND?HWND:this.HWND?this.HWND:0
    Return DllCall("User32\SendMessage", "Ptr", HLV, "UInt", LVM_SETEXTENDEDLISTVIEWSTYLE, "Ptr", StyleMsk, "Ptr", Styles, "Ptr")
  }

  ;选中listview指定行
  ClickRow(Row,HWND:=0){
    Static LVM_GETITEMRECT:=0x100E
    Static WM_LBUTTONDOWN:=0x0201
    Static WM_LBUTTONUP:=0x0202

    HLV:=HWND?HWND:this.HWND?this.HWND:0
    VarSetCapacity(RECT, 16, 0)
    DllCall("User32\SendMessage", "Ptr", HLV, "UInt", LVM_GETITEMRECT, "Ptr", Row - 1, "Ptr", &RECT)
    POINT := NumGet(RECT, 0, "Short") | (NumGet(RECT, 4, "Short") << 16)
    DllCall("user32\PostMessage", "ptr", HLV, "uint", WM_LBUTTONDOWN, "ptr", 0, "ptr", POINT)
    DllCall("user32\PostMessage", "ptr", HLV, "uint", WM_LBUTTONUP, "ptr", 0, "ptr", POINT)
  }

  ;获取目标ListView指定列宽
  GetColumnWidth(Column,HWND:=0) {
    Static LVM_GETCOLUMNWIDTH:= 0x101D

    HLV:=HWND?HWND:this.HWND?this.HWND:0
    Return DllCall("User32\SendMessage", "Ptr", HLV, "UInt", LVM_GETCOLUMNWIDTH, "Ptr", Column - 1, "Ptr", 0, "Ptr")
  }

  ;计算显示指定行所需的大约宽度和高度
  CalcViewRect(Rows:=0,HWND:=0) {
    Static LVM_APPROXIMATEVIEWRECT := 0x1040

    HLV:=HWND?HWND:this.HWND?this.HWND:0
    Rect:=DllCall("User32\SendMessage", "Ptr", HLV, "UInt", LVM_APPROXIMATEVIEWRECT, "Ptr", Rows - 1, "Ptr", 0, "Ptr")
    Return {W: (Rect & 0xFFFF), H: (Rect >> 16) & 0xFFFF}
  }
}

Class ToolTipBox
{
  /*
    Drawtooltip("自绘tooltip窗口5",,,{back_color:0x17ffff,text_color:0xffffff,font_weight:700,font_point:16,font_face:"宋体"})
    TT1:=Drawtooltip("自绘tooltip窗口1",600,100,True)
    TT2:=Drawtooltip("自绘tooltip窗口2",TT1.x,TT1.y+TT1.h+10,True)
    TT3:=Drawtooltip("自绘tooltip窗口3",TT2.x,TT2.y+TT2.h+10,True)
    TT4:=Drawtooltip("自绘tooltip窗口4",TT3.x,TT3.y+TT3.h+10,True)
    参数:
      Text: 文本字符
      xpos: x坐标,为空时跟随鼠标,例如Drawtooltip("Text")
      ypos: y坐标,为空时跟随鼠标
      Style:
        1、为true时自动随机颜色,其它默认。例如Drawtooltip("自绘tooltip窗口",,,True)
        2、为数组对象参数时:
          auto_color:为true时自动随机颜色,back_color与text_color定义无效
          back_color:背景色
          text_color:字体颜色
          font_face:字体名称
          font_point:字号
          font_weight:字体粗细
          Top:上边距
          Bottom:下边距
          Left:左边距
          Right:右边距
          ,例如:Drawtooltip("自绘tooltip窗口",,,{back_color:0x17ffff,text_color:0xffffff,font_weight:700,font_point:16,font_face:"楷体"})
      Timeout: 限定时间自动销毁(毫秒)
    窗口ahk_class:tooltips_class32
  */
  Drawtooltip(Text,xpos:="",ypos:="",Style:="",Timeout:=3500){
    MinLeft:=DllCall("GetSystemMetrics", "Int", 76), MinTop:=DllCall("GetSystemMetrics", "Int", 77)
    , MaxRight:=DllCall("GetSystemMetrics", "Int", 78), MaxBottom:=DllCall("GetSystemMetrics", "Int", 79)
    SysGet, MonCount, MonitorCount
    SysGet, Mon, Monitor
    if !(xpos>=0&&ypos>=0){
      static i:=VarSetCapacity(i,8,0)
      DllCall("GetCursorPos","Ptr",&i),xpos:=NumGet(i,0,"Int"),ypos:=NumGet(i,4,"Int")
    }
    xpos:=(xpos<MinLeft?MinLeft:xpos>MaxRight?MaxRight:xpos), ypos:=(ypos<MinTop?MinTop:ypos>MaxBottom?MaxBottom:ypos)
    If (MonCount>1){
      HMON:=DllCall("User32.dll\MonitorFromPoint", "Int64", (xpos & 0xFFFFFFFF) | (ypos << 32), "UInt", 0, "Ptr")
      NumPut(VarSetCapacity(MIEX, 40 + (32 << !!A_IsUnicode)), MIEX, 0, "UInt")
      if DllCall("User32.dll\GetMonitorInfo", "Ptr", HMON, "Ptr", &MIEX, "Int"){
        MonInfo:={Name: (Name := StrGet(&MIEX + 40, 32)), Num: RegExReplace(Name, ".*(\d+)$", "$1")
          , Left: NumGet(MIEX, 4, "Int"), Top: NumGet(MIEX, 8, "Int")
          , Right: NumGet(MIEX, 12, "Int"), Bottom: NumGet(MIEX, 16, "Int")
          , WALeft: NumGet(MIEX, 20, "Int"), WATop: NumGet(MIEX, 24, "Int")
          , WARight: NumGet(MIEX, 28, "Int"), WABottom: NumGet(MIEX, 32, "Int")
          , Primary: NumGet(MIEX, 36, "UInt")}
        MonLeft:=MonInfo.Left, MonTop:=MonInfo.Top, MonRight:=MonInfo.Right, MonBottom:=MonInfo.Bottom
      }Else
        SysGet, Mon, Monitor
    }
    VarSetCapacity(TOOLINFO, A_PtrSize=8?72:48, 0)
    NumPut(A_PtrSize=8?72:48, &TOOLINFO, 0, "UInt")
    NumPut(TTF_TRACK := 0x20, &TOOLINFO, 4, "UInt")
    NumPut(&Text, &TOOLINFO, A_PtrSize=8?48:36, "Ptr")
    hTT := DllCall("user32\CreateWindowEx", "UInt",0x8, "Str","tooltips_class32", "Ptr",0, "UInt",0x3, "Int",0, "Int",0, "Int",0, "Int",0, "Ptr",A_ScriptHwnd, "Ptr",0, "Ptr",0, "Ptr",0)
    if (!isObject(Style)&&hTT&&Style||isObject(Style)&&hTT&&Style.auto_color) {
      Random,backcolor,0x000000,0xffffff
      Style:=isObject(Style)?Style:{},Style.back_color:=Format("0x{:06X}",backcolor)
      tarr:= StrSplit(RegExReplace(SubStr(Style.back_color,3),"(..)","0x$1,"),",")
      Style.text_color:=Floor(tarr[1]*0.299+tarr[2]*0.587+tarr[3]*0.114)<192?"0xffffff":"0x333333"
    }Else{
      Style:=isObject(Style)?Style:{},Style.back_color :=Style.back_color~="i)^(0x[a-fA-F0-9]{5,6}|\d+)"?Style.back_color: 0xF0F0F0 ;RGB
      ,Style.text_color :=Style.text_color~="i)^(0x[a-fA-F0-9]{5,6}|\d+)"?Style.text_color: 0x1F1F1F ;RGB
    }
    DllCall("uxtheme\SetWindowTheme", "Ptr",hTT, "Ptr",0, "Str","")
    VarSetCapacity(RECT, 16, 0),vRect := (Style.Left>0?Style.Left:8) "," (Style.Top>0?Style.Top:4) "," (Style.Right>0?Style.Right:8) "," (Style.Bottom>0?Style.Bottom:4)
    Loop, Parse, vRect, % ","
      NumPut(A_LoopField, &RECT, A_Index*4-4, "Int")
    DllCall("SendMessage", "Uint", hTT, "Uint", TTM_SETMARGIN := 0x41A, "Uint", 0, "Uint", &RECT)
    DllCall("SendMessage", "Ptr", hTT, "Uint", TTM_SETTIPBKCOLOR := 0x413, "Ptr", ((Style.back_color&255)<<16)+(((Style.back_color>>8)&255)<<8)+(Style.back_color>>16), "Ptr", 0)
    DllCall("SendMessage", "Ptr", hTT, "Uint", TTM_SETTIPTEXTCOLOR := 0x414, "Ptr", ((Style.text_color&255)<<16)+(((Style.text_color>>8)&255)<<8)+(Style.text_color>>16), "Ptr", 0)
    DllCall("SendMessage", "Uint", hTT, "Uint", TTM_SETMAXTIPWIDTH :=0x418, "Uint", 0, "Uint", A_ScreenWidth)
    NumPut(VarSetCapacity(info, A_IsUnicode ? 504 : 344, 0), info, 0, "UInt")
    DllCall("SystemParametersInfo", "UInt", 0x29, "UInt", 0, "Ptr", &info, "UInt", 0)
    SysDefaultFont:=StrGet(&info + 52)<>""?StrGet(&info + 52):"微软雅黑"
    ,Style.font_face :=Style.font_face<>""?Style.font_face:SysDefaultFont
    ,Style.font_point :=Style.font_point>0?Style.font_point:9
    ,Style.font_weight :=Style.font_weight?Style.font_weight:400
    ,Style.font_height := -Round(Style.font_point*A_ScreenDPI/72)
    hFont := DllCall("gdi32\CreateFont", "Int",Style.font_height, "Int",0, "Int",0, "Int",0, "Int",Style.font_weight, "UInt",0, "UInt",0 ,"UInt",0, "UInt",0, "UInt",0, "UInt",0, "UInt",0, "UInt",0, "Str",Style.font_face, "Ptr")
    DllCall("SendMessage", "Ptr", hTT, "Uint", WM_SETFONT := 0x30, "Ptr", hfont, "Ptr", 0)
    DllCall("SendMessage", "Uint", hTT, "Uint", TTM_ADDTOOL:=A_IsUnicode?0x432:0x404, "Uint", 0, "Uint", &TOOLINFO)
    DllCall("SendMessage", "Uint", hTT, "Uint", TTM_TRACKPOSITION := 0x412, "Uint", 0, "Uint", (xpos&0xFFFF)|(ypos<<16))
    DllCall("SendMessage", "Uint", hTT, "Uint", TTM_TRACKACTIVATE := 0x411, "Uint", 1, "Uint", &TOOLINFO)
    VarSetCapacity( size, 16, 0 ),DllCall( "GetClientRect", "Ptr", htt, "Ptr", &size )
    DllCall( "ClientToScreen", "Ptr", htt, "Ptr", &size )
    width := NumGet( size, 8, "Int" ), height := NumGet( size, 12, "Int" )
    if (Timeout>0){
      flag:=Func("DllCall").Bind("DestroyWindow", "ptr", hTT)
      SetTimer, % flag,% "-" Timeout
    }

    Return {HWND:hTT,w:width,h:height,x:xpos,y:ypos}
  }

  /*
    HWND1:=ToolTip("Text..1",600,100,1,True)
    HWND2:=ToolTip("Text..2",600,HWND1.y+HWND1.h+10,2,True)
    HWND3:=ToolTip("Text..3",600,HWND2.y+HWND2.h+10,3,True)
    HWND4:=ToolTip("Text..4",600,HWND3.y+HWND3.h+10,4,True)
    HWND5:=ToolTip("Text..5",,,5,True)

    ToolTip(Text,xpos:="",ypos:="",WhichToolTip:=1,Style:="",RelatedArea:="Screen",Timeout:=3000)
    参数:
      Text: 文本字符
      xpos: x坐标,为空时跟随鼠标,例如ToolTip("Text")
      ypos: y坐标,为空时跟随鼠标
      WhichToolTip: ToolTip编号1~20,例如ToolTip("Text",,,3)
      Style:
        1、为true时自动随机颜色,其它默认。例如ToolTip("Text..3",,,3,True)
        2、为数组对象参数时例如{back_color:0x17ffff,text_color:0xffffff}
          当auto_color:为true时自动随机颜色,back_color与text_color定义无效
          ,例如ToolTip("Text..3",,,3,{back_color:0x17ffff,text_color:0xffffff})
      RelatedArea:为多个命令设置坐标模式, 相对于活动窗口还是屏幕,参数为Screen、Relative、Window、Client
      Timeout: 限定时间自动销毁(毫秒)
  */
  ToolTip(Text,xpos:="",ypos:="",WhichToolTip:=1,Style:="",RelatedArea:="Screen",Timeout:=3000){
    if (WhichToolTip<1||WhichToolTip>20||Trim(Text)="")
      Return False
    if RelatedArea In Screen,Relative,Window,Client
      CoordMode,ToolTip,%RelatedArea%
    Gui +OwnDialogs
    ToolTip,%Text%,xpos,ypos,WhichToolTip
    HWND:=WinExist("ahk_class tooltips_class32")
    if (!isObject(Style)&&HWND&&Style||isObject(Style)&&HWND&&Style.auto_color) {
      Random,backcolor,0x000000,0xffffff
      Style:=isObject(Style)?Style:{},Style.back_color:=Format("0x{:06X}",backcolor)
      tarr:= StrSplit(RegExReplace(SubStr(Style.back_color,3),"(..)","0x$1,"),",")
      Style.text_color:=Floor(tarr[1]*0.299+tarr[2]*0.587+tarr[3]*0.114)<192?"0xffffff":"0x333333"
    }
    if (isObject(Style)&&HWND) {
      DllCall("UxTheme.dll\SetWindowTheme", "ptr", hwnd, "Ptr", 0, "UintP", 0)
      if Style.back_color~="i)^(0x[a-fA-F0-9]{5,6}|\d+)"
        DllCall("SendMessage", "Ptr", hwnd, "Uint", 1043, "Ptr", ((Style.back_color&255)<<16)+(((Style.back_color>>8)&255)<<8)+(Style.back_color>>16), "Ptr", 0)
      if Style.text_color~="i)^(0x[a-fA-F0-9]{5,6}|\d+)"
        DllCall("SendMessage", "Ptr", hwnd, "Uint", 1044, "Ptr", ((Style.text_color&255)<<16)+(((Style.text_color>>8)&255)<<8)+(Style.text_color>>16), "Ptr", 0)
    }
    ;hfont:=DllCall("SendMessage", "Ptr", hwnd, "Uint", WM_GETFONT:= 0x31, "Ptr", 0, "Ptr", 0)
    ;if hFont&&HWND
    ;	DllCall("SendMessage", "Ptr", hwnd, "Uint", 0x30, "Ptr", hfont, "Ptr", 0)
    if !(xpos>=0&&ypos>=0){
      static i:=VarSetCapacity(i,8,0)
      DllCall("GetCursorPos","Ptr",&i),xpos:=NumGet(i,0,"Int"),ypos:=NumGet(i,4,"Int")
    }
    VarSetCapacity( size, 16, 0 ),DllCall( "GetClientRect", "Ptr", HWND, "Ptr", &size )
    DllCall( "ClientToScreen", "Ptr", HWND, "Ptr", &size )
    xpos := NumGet( size, 0, "Int"), ypos := NumGet( size, 4, "Int")
    width := NumGet( size, 8, "Int" ), height := NumGet( size, 12, "Int" )
    if (Timeout>0){
      flag:=Func("DllCall").Bind("DestroyWindow", "ptr", HWND)
      SetTimer, % flag,% "-" Timeout
    }

    Return {HWND:HWND,w:width,h:height,x:xpos,y:ypos}
  }
}

 

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