Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Dynamically create SysListView
#1
Hi,

I created a function DynamicLV, I want to create SysListView dynamically
At present, some features have been implemented, but there are still some problems below:

 1. Line 37: The font settings are not in effect 
 2. How to implement: After the dialog box pops up, the first line of text is selected by default
 3. How to implement: After pressing the letter that begins with a line, close the dialog box and output the index of the selected line
 4. How to implement: Do not display the header row where Lable is located
 5. How to implement: Display separator lines between lines of text
 6. How to implement: The height of the dialog box automatically adapts to the number of lines of text

Most of the code comes from the forum, with some modifications, There may be an easier way to implement it, 

Thanks in advance for any advice and help
david

The final result I'm looking forward to is as follows

[Image: abc.png]

Macro Macro4
Trigger Aq     Help - how to add the trigger to the macro
Code:
Copy      Help
_s=
;A I'm in the line 1
;B I'm in the line 2
;C I'm in the line 3
;D I'm in the line 4
;E I'm in the line 5

_i=DynamicLV(_s)

mes _i

----------------------------------------------------------------------------------------------------------------------------------------
Function DynamicLV
Code:
Copy      Help
function# str'text
out
;https://www.quickmacros.com/forum/showthread.php?tid=5936&pid=28797#pid28797
str dd=
;BEGIN DIALOG
;0 "" 0x90080AC8 0x0 0 0 184 108 "Dialog"
;3 SysListView32 0x5403804D 0x204 0 0 184 108 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040C02 "*" "" "" ""

if(!ShowDialog(dd &sub.DlgProc 0)) ret


#sub DlgProc v
function# hDlg message wParam lParam

int hsys32=id(3 hDlg)
sel message
,case WM_INITDIALOG

,SendMessage hsys32 LVM_SETIMAGELIST LVSIL_SMALL 0
,
,int es=LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_SUBITEMIMAGES
,SendMessage hsys32 LVM_SETEXTENDEDLISTVIEWSTYLE es es
,sub.LvAddCol hsys32 0 "Label" -90
,sub.LvAddCol hsys32 1 "ID" -10

;,Fill-in values to sys32
,SendMessage hsys32 LVM_DELETEALLITEMS 0 0
,str col0=text

,int n=numlines(col0)
,for int'i 0 n
,,_s.getl(col0 i)
,,sub.LvAdd hsys32 i 0 0 _s i+1
,
,__Font f.CreateNew(hsys32 "Microsoft YaHei Mono" 11) ;;change this
,SendMessage hsys32 WM_SETFONT f 1
,
,case WM_DESTROY
,case WM_COMMAND goto messages2
,case WM_NOTIFY goto messages3
ret
;messages2
sel wParam
,case IDOK
,case IDCANCEL
ret 1
;messages3
NMHDR* nh=+lParam
NMITEMACTIVATE* na=+nh
int j
sel nh.code
,case LVN_ITEMCHANGED
,if(na.uNewState&LVIS_SELECTED and na.uOldState&LVIS_SELECTED=0) ;;listview item selected
,,sel nh.idFrom
,,,case 3
,,,j=na.iItem;; if(j<0 or j>=aFiles.len) ret
,,,out j
ret j
,,,
#sub LvAddCol
function hlv index $txt width

;Adds column to SysListView32 control that has LVS_REPORT style (1).
;Index of first colunm is 0. If index <0, adds to the end.
;If width <0, it is interpreted as -percentage.

LVCOLUMNW col.mask=LVCF_WIDTH|LVCF_TEXT
col.pszText=@txt
if(width<0) RECT r; GetClientRect hlv &r; width=-width*r.right/100
col.cx=width
if(index<0) index=0x7fffffff
SendMessage hlv LVM_INSERTCOLUMNW index &col

#sub LvAdd
function# hlv index lparam image ~s [~s1] [~s2] [~s3] [~s4] [~s5] [~s6] [~s7] [~s8] [~s9]

;Adds item to SysListView32 control that has LVS_REPORT style and 1 to 10 columns.

if(index<0) index=0x7FFFFFFF
LVITEMW lvi.mask=LVIF_TEXT|LVIF_PARAM|LVIF_IMAGE
lvi.iItem=index
lvi.pszText=@s
lvi.lParam=lparam
lvi.iImage=image
index=SendMessage(hlv LVM_INSERTITEMW 0 &lvi)

if index>=0
,int i; str* p=&s
,for i 1 getopt(nargs)-4
,,lvi.iItem=index
,,lvi.iSubItem=i
,,lvi.pszText=@p[i]
,,SendMessage(hlv LVM_SETITEMTEXTW index &lvi)
ret index
#2
How to see the function definition of the QM AutoText list QM_PopupList(I wanted a feature similar to it), I did not find it in the QM system folder
#3
Not open-source.
#4
try this should cover all 6 requests
added additional functionality
enter key also returns selected item idex
double left mouse click on item also does the same

Function DynamicLV
Code:
Copy      Help
;/
function# str'text
out
str dd=
F
;BEGIN DIALOG
;0 "" 0x90080AC8 0x0 0 0 184 108 "Dialog"
;3 SysListView32 0x5403C04D 0x204 0 0 184 108 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040C00 "*" "" "" ""

int iii= ShowDialog(dd &sub.DlgProc 0)
ret iii

#sub DlgProc v
function# hDlg message wParam lParam

int hsys32=id(3 hDlg)
sel message
,case WM_INITDIALOG
,__Font- f.CreateNew(hsys32 "Microsoft YaHei Mono" 11) ;;change this
,f.SetDialogFont(hDlg "3")    
,int es=LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_GRIDLINES
,SendMessage hsys32 LVM_SETEXTENDEDLISTVIEWSTYLE es es
,TO_LvAddCol hsys32 0 "" -90
,TO_LvAddCol hsys32 1 "" -10
;,Fill-in values to sys32
,int n=numlines(text)
,for int'i 0 n
,,_s.getl(text i)
,,TO_LvAdd hsys32 i 0 0 _s i+1
,RECT r.left=LVIR_BOUNDS; SendMessage(hsys32 LVM_GETITEMRECT 0 &r)
,int xy=SendMessage(hsys32 LVM_APPROXIMATEVIEWRECT n -1|-1)
,int width = xy & 0x0000FFFF
,int hh = xy>>16&0x0000FFFF
,siz width+4 hh hsys32
,siz width+11 hh-r.bottom+8 hDlg
,sub.LvSelect hsys32 0
,case WM_DESTROY
,case WM_COMMAND goto messages2
,case WM_NOTIFY goto messages3    
ret
;messages2
sel wParam
,case IDOK
,int ii=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,DT_EndDialog(hDlg ii)
,case IDCANCEL
,DT_EndDialog(hDlg 0)
ret 1
;messages3
NMHDR* nh=+lParam
sel nh.idFrom
,case 3
,sel nh.code
,,case LVN_KEYDOWN
,,NMLVKEYDOWN* lvk=+nh
,,for i 0 numlines(text)
,,,_s.getl(text i)
,,,if(_s[0] = lvk.wVKey)
,,,,DT_EndDialog(hDlg i)
,,,,break
,,case NM_DBLCLK;;on double left click of listview item
,,;lvSelect
,,i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,,DT_EndDialog(hDlg i)

#sub LvSelect
function hlv item [flags] ;;flags: 1 don't deselect previous, 2 don't set focus, 4 ensure visible, 8 deselect

;Selects listview item.
;To select none, use item -1.
;To select all, use item -1 and flag 8.
;Note that listview controls with LVS_SINGLESEL style can have max 1 item selected.

LVITEMW li.stateMask=LVIS_FOCUSED|LVIS_SELECTED
if(item>=0)
,if(flags&9=0) SendMessage hlv LVM_SETITEMSTATE -1 &li
,if(flags&8=0) li.state=LVIS_SELECTED; if(flags&2=0) li.state|LVIS_FOCUSED
,SendMessage hlv LVM_SETITEMSTATE item &li
,if(flags&4) SendMessage hlv LVM_ENSUREVISIBLE item 0
else
,if(flags&8) li.state=LVIS_SELECTED
,SendMessage hlv LVM_SETITEMSTATE -1 &li

added functionality if alt+f4 is used to close dialog macro will end
Macro Macro9
Code:
Copy      Help
_s=
;A  I'm in the line 1
;B  I'm in the line 2
;C  I'm in the line 3
;D  I'm in the line 4
;E  I'm in the line 5

int i=DynamicLV(_s)

if i=1000
,ret;; end if alt+f4 was used to closed dialog
out i    
str ss
ss.getl(_s i)
out ss
#5
@Kevin 

Thanks for your help, 
Worked well, 

How to achieve?
1.When I press the esc key, close the dialog directly, do not output(Don't do anything)
2.make the dialog appear below the input cursor,e.g:
DynamicLV(_s) ;;Appears at the input cursor, If the input cursor is not found, Appears in the center of the screen
DynamicLV(_s 0) ;;Appears in the center of the screen
DynamicLV(_s 1) ;;Appears at the input cursor

My intention is to use it in the AutoText, like the below
I also want to implement that:
when I press the right mouse button on any item in this DynamicLV dialog,
then the dialog closes and then navigates to the subfunction where the dialog is located, e.g: sub.Sub1 , This way I can easily edit it, Is this possible?

Autotext autotext8
Trigger $t     Help - how to add the trigger to the macro
Code:
Copy      Help
/b/i/c/m
te :sub.Sub1 ;;1 test DynamicLV
te :sub.Sub2 ;;2 test

#sub Sub1 m
_s=
;A  I'm in the line 1
;B  I'm in the line 2
;C  I'm in the line 3
;D  I'm in the line 4
;E  I'm in the line 5
;F  I'm in the line 6

_i=DynamicLV(_s)

sel _i+1
,case 1
,mes "I'm in the line 1"
,case 2
,mes "I'm in the line 2"
,case 3
,mes "I'm in the line 3"
,case 4
,mes "I'm in the line 4"
,case 5
,mes "I'm in the line 5"
,case 6
,mes "I'm in the line 6"

#sub Sub2 m
mes "hello world"
#6
somehow the cancel part got messed up
for #1
change
Code:
Copy      Help
,case IDCANCEL
,DT_EndDialog(hDlg 0)

to
Code:
Copy      Help
,case IDCANCEL
,DT_EndDialog(hDlg 1000)
#7
for #2 
--------------------------------------------------
function# str'text
int x y
GetCaretXY x y

--------------------------------------------------
case WM_INITDIALOG
mov  x y+20 hDlg
--------------------------------------------------
How to achieve?
If the input cursor is not found, Appears in the center of the screen, Using the above code, the dialog appears in the upper-left corner of the screen
DynamicLV(_s 0) ;;Appears in the center of the screen
DynamicLV(_s 1) ;;Appears at the input cursor
#8
you almost have it

just need a couple more things

Function DynamicLV
Code:
Copy      Help
;/
function# str'text [flags];;optional .1 show dialog at caret position if possible. 0 or omitted show dialog at center of screen(default)
out
if(flags&1)
,int xx yy isCaret
,isCaret = GetCaretXY(xx yy)
str dd=
;BEGIN DIALOG
;0 "" 0x90080AC8 0x0 0 0 184 108 "Dialog"
;3 SysListView32 0x5403C04D 0x204 0 0 184 108 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040C00 "*" "" "" ""

int iii= ShowDialog(dd &sub.DlgProc 0)
ret iii

#sub DlgProc v
function# hDlg message wParam lParam

int hsys32=id(3 hDlg)
sel message
,case WM_INITDIALOG
,__Font- f.CreateNew(hsys32 "Microsoft YaHei Mono" 11) ;;change this
,f.SetDialogFont(hDlg "3")    
,int es=LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_GRIDLINES
,SendMessage hsys32 LVM_SETEXTENDEDLISTVIEWSTYLE es es
,TO_LvAddCol hsys32 0 "" -90
,TO_LvAddCol hsys32 1 "" -10
;,Fill-in values to sys32
,int n=numlines(text)
,for int'i 0 n
,,_s.getl(text i)
,,TO_LvAdd hsys32 i 0 0 _s i+1
,RECT r.left=LVIR_BOUNDS; SendMessage(hsys32 LVM_GETITEMRECT 0 &r)
,int xy=SendMessage(hsys32 LVM_APPROXIMATEVIEWRECT n -1|-1)
,int width = xy & 0x0000FFFF
,int hh = xy>>16&0x0000FFFF
,siz width+4 hh hsys32
,siz width+11 hh-r.bottom+8 hDlg
,sub.LvSelect hsys32 0
,if(isCaret > 0) ;; if caret is found  and flag is 1 move dialog to caret
,,mov xx yy+25 hDlg
,case WM_DESTROY
,case WM_COMMAND goto messages2
,case WM_NOTIFY goto messages3    
ret
;messages2
sel wParam
,case IDOK
,int ii=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,DT_EndDialog(hDlg ii)
,case IDCANCEL
,DT_EndDialog(hDlg 1000);;;return this to know dialog was closed  using alt+F4 or esc
ret 1
;messages3
NMHDR* nh=+lParam
sel nh.idFrom
,case 3
,sel nh.code
,,case LVN_KEYDOWN
,,NMLVKEYDOWN* lvk=+nh
,,for i 0 numlines(text)
,,,_s.getl(text i)
,,,if(_s[0] = lvk.wVKey)
,,,,DT_EndDialog(hDlg i)
,,,,break
,,case NM_DBLCLK;;on double left click of listview item
,,i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,,DT_EndDialog(hDlg i)

#sub LvSelect
function hlv item [flags] ;;flags: 1 don't deselect previous, 2 don't set focus, 4 ensure visible, 8 deselect

;Selects listview item.
;To select none, use item -1.
;To select all, use item -1 and flag 8.
;Note that listview controls with LVS_SINGLESEL style can have max 1 item selected.

LVITEMW li.stateMask=LVIS_FOCUSED|LVIS_SELECTED
if(item>=0)
,if(flags&9=0) SendMessage hlv LVM_SETITEMSTATE -1 &li
,if(flags&8=0) li.state=LVIS_SELECTED; if(flags&2=0) li.state|LVIS_FOCUSED
,SendMessage hlv LVM_SETITEMSTATE item &li
,if(flags&4) SendMessage hlv LVM_ENSUREVISIBLE item 0
else
,if(flags&8) li.state=LVIS_SELECTED
,SendMessage hlv LVM_SETITEMSTATE -1 &li
 
calling examples
Code:
Copy      Help
int i=DynamicLV(_s);;center of screen
int i=DynamicLV(_s 1);;below cursor
#9
@Kevin
Thanks again, works well, nice features and cases  Smile
#10
@Kevin
About:
when I press the right mouse button on any item in this DynamicLV dialog,
then the dialog closes and then navigates to the subfunction where the dialog is located, e.g: sub.Sub1 , This way I can easily edit it

I think it's possible, see the picture below
[Image: a.png]


Idea When the DynamicLV dialog is displayed, it will display the name of the autotext file being operated in the Running items toolbar of the QM
So, get it -> open it -> search the file for right-click item's text, e.g: A  I'm in the line 1  -> Highlight it
This requires more programming skills 
Smile

Some code I found:

Macro Macro6
Code:
Copy      Help
;Display all threads
int i n=EnumQmThreads(0 0 0 0)
ARRAY(QMTHREAD) a.create(n)
for i 0 EnumQmThreads(&a[0] n 0 0)
,out _s.getmacro(a[i].qmitemid 1)


;Open the autotext file
mac+ "autotext8"
#11
Maybe this can help.

Macro Macro3229
Code:
Copy      Help
;Assume you want to add items to some list, menu, etc and implement a "go to source code" command.
;For it use function Statement in the function that adds a single item.
;This is a simplest example.

sub.Add("one")
1
sub.Add("two")


#sub Add
function $text

;get caller's QM item id and position in source code
int iid pos=Statement(1 0 0 iid)

;go to source code now
mac+ iid
int h=GetQmCodeEditor
act h
SendMessage h SCI.SCI_GOTOPOS pos 0

;Normally you would add iid/pos to an array and go to source code later on user request etc.
;Create a class. Let Add be a function of that class. Let the array be a class field (variable).
#12
I defined it as a function  WAI
Then called in a subfunction of the AutoText item,
But it will always execute
Also, I didn't find the event settings on the item by mouse Right-click

It would be much better if the operation on WAI was defined as an argument in the DynamicLV function, e.g: DynamicLV(_s 1 1) ;;set 1 can locate by right-clicking

Autotext autotext8
Trigger $t     Help - how to add the trigger to the macro
Code:
Copy      Help
/b/i/c/m
te :sub.Sub1 ;;1 test DynamicLV

#sub Sub1 m
WAI "a"
_s=
;A  I'm in the line 1
;B  I'm in the line 2
;C  I'm in the line 3

_i=DynamicLV(_s)

sel _i+1
,case 1
,mes "I'm in the line 1"
,case 2
,mes "I'm in the line 2"
,case 3
,mes "I'm in the line 3"
,case 4
,mes "I'm in the line 4"
,case 5
,mes "I'm in the line 5"
,case 6
,mes "I'm in the line 6"

Function WAI
Code:
Copy      Help
function $text ;;Where Am I

;get caller's QM item id and position in source code
int iid pos=Statement(1 0 0 iid)

;go to source code now
mac+ iid
int h=GetQmCodeEditor
act h
SendMessage h SCI.SCI_GOTOPOS pos 0

;Normally you would add iid/pos to an array and go to source code later on user request etc.
;Create a class. Let Add be a function of that class. Let the array be a class field (variable).
#13
Now, Use the following code, I can open the aototext file where this item is located by right-clicking. 
However, there is no implementation of positioning to the subfunction, how to Search for item text in the QM Code Editor Huh
e.g: search  A  I'm in the line 1   Note: There is a space in front

-------------------------------------------------------------------------------------------------

 messages3      add:

        case NM_RCLICK ;;on right click of listview item
        i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
        str ss.getl(text i)
        out ss
        DT_EndDialog hDlg 1000
        n=EnumQmThreads(0 0 0 0)
        ARRAY(QMTHREAD) a.create(n)
        for _i 0 EnumQmThreads(&a[0] n 0 0)
            _s.getmacro(a[_i].qmitemid 1)
        mac+ _s
         Todo: 
         1.In the QM Editor, search for the text of the right-clicked item
         2.Highlight flashes to show it


about:
_s.getmacro(a[_i].qmitemid 1)

Because it is possible that other functions will also running, Which number should I set? 34?
--------------------------------------------------------------------------------------------------------
getmacro([$macro|iid] [what])   ;;`Gets macro text, name, etc.`    what: 0 text, 1 name, 2 trigger.
 Obsolete what: 3 type ("0" macro, "1" function, "2" menu, "3" toolbar, "4" autotext, "5" folder, "6" member, "7" file link), 4 disabled, 5 encrypted, 6 shared, 7 id, 8 read-only.
#14
Don't use EnumQmThreads. Use Statement at the start of the function (see my previous post). Get caller's text with _s.getmacro(iid), and parse that text.

To highlight, use SendMessage(GetQmCodeEditor SCI.XXX ...) where XXX is a Scintilla message documented in the Scintilla website. I don't remember what message to use.
#15
Thanks for the explanation,
sorry, I don't quite understand how to use Statement in the AutoText subfunction

about highlight , I found a piece of code in the forum
------------------------------------------------------------------------
#sub FlashCodeLine
function curPos hce
if(!hce) hce=GetQmCodeEditor
int indicator=9
int line=SendMessage(hce SCI.SCI_LINEFROMPOSITION curPos 0)
SendMessage(hce SCI.SCI_SETINDICATORCURRENT indicator 0)
SendMessage(hce SCI.SCI_INDICSETALPHA indicator 100)
SendMessage(hce SCI.SCI_INDICSETFORE indicator 0x00FF00)
SendMessage(hce SCI.SCI_INDICSETSTYLE indicator SCI.INDIC_STRAIGHTBOX)
SendMessage(hce SCI.SCI_INDICSETUNDER indicator TRUE)
int lsp=SendMessage(hce SCI.SCI_POSITIONFROMLINE line 0)
int lep=SendMessage(hce SCI.SCI_GETLINEENDPOSITION line 0)
rep 4
    SendMessage(hce SCI.SCI_INDICATORFILLRANGE lsp lep-lsp)
    0.25
    SendMessage(hce SCI.SCI_INDICATORCLEARRANGE lsp lep-lsp)
    0.25
SendMessage(hce SCI.SCI_SETINDICATORCURRENT 0 0)
#16
Function DynamicLV
Code:
Copy      Help
;/
function str'items

int iid to=Statement(1 0 0 iid)
str s.getmacro(iid)
s.left(s to)
out s
;Then on right-click parse s to get item text position in s. Then mac+ iid, SCI_GOTOPOS, etc, like in my previous post.
#17
I still don't quite understand how to use the above Function,  Wink
Below is the complete sample code, with two features not implemented and a note after the code

Autotext autotext8
Trigger $t     Help - how to add the trigger to the macro
Code:
Copy      Help
/b/i/c/m
te :sub.Sub1 ;;1 test DynamicLV

#sub Sub1 m
_s=
;A  I'm in the line 1
;B  I'm in the line 2
;C  I'm in the line 3

_i=DynamicLV(_s 1)

sel _i+1
,case 1
,mes "I'm in the line 1"
,case 2
,mes "I'm in the line 2"
,case 3
,mes "I'm in the line 3"
,case 4
,mes "I'm in the line 4"
,case 5
,mes "I'm in the line 5"
,case 6
,mes "I'm in the line 6"



Function DynamicLV
Code:
Copy      Help
;/
function# str'text [flags];;optional .1 show dialog at caret position if possible. 0 or omitted show dialog at center of screen(default)
out
if(flags&1)
,int xx yy isCaret
,isCaret = GetCaretXY(xx yy)
str dd=
;BEGIN DIALOG
;0 "" 0x90080AC8 0x0 0 0 184 108 "Dialog"
;3 SysListView32 0x5403C04D 0x204 0 0 184 108 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040C00 "*" "" "" ""

int iii= ShowDialog(dd &sub.DlgProc 0)
ret iii

#sub DlgProc v
function# hDlg message wParam lParam

int hsys32=id(3 hDlg)
sel message
,case WM_INITDIALOG
,__Font- f.CreateNew(hsys32 "Microsoft YaHei Mono" 11) ;;change this
,f.SetDialogFont(hDlg "3")
,int es=LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_GRIDLINES
,SendMessage hsys32 LVM_SETEXTENDEDLISTVIEWSTYLE es es
,TO_LvAddCol hsys32 0 "" -90
,TO_LvAddCol hsys32 1 "" -10
;,Fill-in values to sys32
,int n=numlines(text)
,for int'i 0 n
,,_s.getl(text i)
,,TO_LvAdd hsys32 i 0 0 _s i+1
,RECT r.left=LVIR_BOUNDS; SendMessage(hsys32 LVM_GETITEMRECT 0 &r)
,int xy=SendMessage(hsys32 LVM_APPROXIMATEVIEWRECT n -1|-1)
,int width = xy & 0x0000FFFF
,int hh = xy>>16&0x0000FFFF
,siz width+4 hh hsys32
,siz width+11 hh-r.bottom+8 hDlg
,sub.LvSelect hsys32 0
,if(isCaret > 0) ;; if caret is found  and flag is 1 move dialog to caret
,,mov xx yy+25 hDlg
,case WM_DESTROY
,case WM_COMMAND goto messages2
,case WM_NOTIFY goto messages3
ret
;messages2
sel wParam
,case IDOK
,int ii=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,DT_EndDialog(hDlg ii)
,case IDCANCEL
,DT_EndDialog(hDlg 1000);;;return this to know dialog was closed  using alt+F4 or esc
ret 1
;messages3
NMHDR* nh=+lParam
sel nh.idFrom
,case 3
,sel nh.code
,,case LVN_KEYDOWN
,,NMLVKEYDOWN* lvk=+nh
,,for i 0 numlines(text)
,,,_s.getl(text i)
,,,if(_s[0] = lvk.wVKey)
,,,,DT_EndDialog(hDlg i)
,,,,break
,,case NM_DBLCLK ;;on double left click of listview item
,,i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,,DT_EndDialog(hDlg i)
,,out i
,,case NM_RCLICK ;;____________________________________________________________right-click listview item,Save the text to ss
,,i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,,str ss.getl(text i)
,,out ss
,,DT_EndDialog hDlg 1000
,,n=EnumQmThreads(0 0 0 0) ;;__________________________________________________Todo1: use EnumQmThreads open autotext item
,,ARRAY(QMTHREAD) a.create(n)
,,for _i 0 EnumQmThreads(&a[0] n 0 0)
,,,_s.getmacro(a[_i].qmitemid 1)
,,mac+ _s
,,
,,;;;__________________________________________________________________________Todo2: Navigate to the Line where ss is located
,,
,,;sub.FlashCodeLine curPos hce ;;_____________________________________________FlashCodeLine ss line


#sub LvSelect
function hlv item [flags] ;;flags: 1 don't deselect previous, 2 don't set focus, 4 ensure visible, 8 deselect

;Selects listview item.
;To select none, use item -1.
;To select all, use item -1 and flag 8.
;Note that listview controls with LVS_SINGLESEL style can have max 1 item selected.

LVITEMW li.stateMask=LVIS_FOCUSED|LVIS_SELECTED
if(item>=0)
,if(flags&9=0) SendMessage hlv LVM_SETITEMSTATE -1 &li
,if(flags&8=0) li.state=LVIS_SELECTED; if(flags&2=0) li.state|LVIS_FOCUSED
,SendMessage hlv LVM_SETITEMSTATE item &li
,if(flags&4) SendMessage hlv LVM_ENSUREVISIBLE item 0
else
,if(flags&8) li.state=LVIS_SELECTED
,SendMessage hlv LVM_SETITEMSTATE -1 &li

#sub FlashCodeLine
function curPos hce
if(!hce) hce=GetQmCodeEditor
int indicator=9
int line=SendMessage(hce SCI.SCI_LINEFROMPOSITION curPos 0)
SendMessage(hce SCI.SCI_SETINDICATORCURRENT indicator 0)
SendMessage(hce SCI.SCI_INDICSETALPHA indicator 100)
SendMessage(hce SCI.SCI_INDICSETFORE indicator 0x00FF00)
SendMessage(hce SCI.SCI_INDICSETSTYLE indicator SCI.INDIC_STRAIGHTBOX)
SendMessage(hce SCI.SCI_INDICSETUNDER indicator TRUE)
int lsp=SendMessage(hce SCI.SCI_POSITIONFROMLINE line 0)
int lep=SendMessage(hce SCI.SCI_GETLINEENDPOSITION line 0)
rep 4
;;;;SendMessage(hce SCI.SCI_INDICATORFILLRANGE lsp lep-lsp)
;;;;0.25
;;;;SendMessage(hce SCI.SCI_INDICATORCLEARRANGE lsp lep-lsp)
;;;;0.25
SendMessage(hce SCI.SCI_SETINDICATORCURRENT 0 0)
#18
this covers it


Autotext Autotext8
Trigger $t     Help - how to add the trigger to the macro
Code:
Copy      Help
/b/i/c/m
te :sub.Sub1 ;;1 test DynamicLV
te :sub.Sub2 ;;2 test

#sub Sub1 m
_s=
;A  I'm in the line 1
;B  I'm in the line 2
;C  I'm in the line 3
;D  I'm in the line 4
;E  I'm in the line 5
;F  I'm in the line 6

_i=DynamicLV(_s 1)
if _i=1000
,ret;; end if alt+f4 or esc was used to closed dialog
str ss
ss.getl(_s _i)
mes ss

#sub Sub2 m
mes "hello world"
Function DynamicLV
Code:
Copy      Help
;/
function# str'text [flags];;optional .1 show dialog at caret position if possible. 0 or omitted show dialog at center of screen(default)

int iid to=Statement(1 0 0 iid)
str ss.getmacro(iid)
ss.left(ss to)
if(flags&1)
,int xx yy isCaret
,isCaret = GetCaretXY(xx yy)
str dd=
;BEGIN DIALOG
;0 "" 0x90080AC8 0x0 0 0 184 108 "Dialog"
;3 SysListView32 0x5403C04D 0x204 0 0 184 108 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040C00 "*" "" "" ""

int iii= ShowDialog(dd &sub.DlgProc 0)
ret iii

#sub DlgProc v
function# hDlg message wParam lParam

int hsys32=id(3 hDlg)
sel message
,case WM_INITDIALOG
,__Font- f.CreateNew(hsys32 "Microsoft YaHei Mono" 11) ;;change this
,f.SetDialogFont(hDlg "3")    
,int es=LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_GRIDLINES
,SendMessage hsys32 LVM_SETEXTENDEDLISTVIEWSTYLE es es
,TO_LvAddCol hsys32 0 "" -90
,TO_LvAddCol hsys32 1 "" -10
;,Fill-in values to sys32
,int n=numlines(text)
,for int'i 0 n
,,_s.getl(text i)
,,TO_LvAdd hsys32 i 0 0 _s i+1
,RECT r.left=LVIR_BOUNDS; SendMessage(hsys32 LVM_GETITEMRECT 0 &r)
,int xy=SendMessage(hsys32 LVM_APPROXIMATEVIEWRECT n -1|-1)
,int width = xy & 0x0000FFFF
,int hh = xy>>16&0x0000FFFF
,siz width+4 hh hsys32
,siz width+11 hh-r.bottom+8 hDlg
,sub.LvSelect hsys32 0
,if(isCaret > 0) ;; if caret is found  and flag is 1 move dialog to caret
,,mov xx yy+25 hDlg
,case WM_DESTROY
,case WM_COMMAND goto messages2
,case WM_NOTIFY goto messages3    
ret
;messages2
sel wParam
,case IDOK
,int ii=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,DT_EndDialog(hDlg ii)
,case IDCANCEL
,DT_EndDialog(hDlg 1000);;;return this to know dialog was closed  using alt+F4 or esc
ret 1
;messages3
NMHDR* nh=+lParam
sel nh.idFrom
,case 3
,sel nh.code
,,case LVN_KEYDOWN
,,NMLVKEYDOWN* lvk=+nh
,,for i 0 numlines(text)
,,,_s.getl(text i)
,,,if(_s[0] = lvk.wVKey)
,,,,DT_EndDialog(hDlg i)
,,,,break
,,case NM_DBLCLK;;on double left click of listview item
,,i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,,DT_EndDialog(hDlg i)
,,case NM_RCLICK;;on right click of listview item
,,i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,,str lviText.getl(text i)
,,out lviText
,,DT_EndDialog(hDlg 1000)
,,int posF=find(ss lviText 0)
,,sub.FlashCodeLine(posF iid)
#sub LvSelect
function hlv item [flags] ;;flags: 1 don't deselect previous, 2 don't set focus, 4 ensure visible, 8 deselect

;Selects listview item.
;To select none, use item -1.
;To select all, use item -1 and flag 8.
;Note that listview controls with LVS_SINGLESEL style can have max 1 item selected.

LVITEMW li.stateMask=LVIS_FOCUSED|LVIS_SELECTED
if(item>=0)
,if(flags&9=0) SendMessage hlv LVM_SETITEMSTATE -1 &li
,if(flags&8=0) li.state=LVIS_SELECTED; if(flags&2=0) li.state|LVIS_FOCUSED
,SendMessage hlv LVM_SETITEMSTATE item &li
,if(flags&4) SendMessage hlv LVM_ENSUREVISIBLE item 0
else
,if(flags&8) li.state=LVIS_SELECTED
,SendMessage hlv LVM_SETITEMSTATE -1 &li
,
#sub FlashCodeLine
function curPos iid [hce]
if(!hce) hce=GetQmCodeEditor
mac+ iid
act hce
SendMessage hce SCI.SCI_GOTOPOS curPos 0
int indicator=19
SendMessage(hce SCI.SCI_SETINDICATORCURRENT indicator 0)
SendMessage(hce SCI.SCI_INDICSETALPHA indicator 100)
SendMessage(hce SCI.SCI_INDICSETFORE indicator 0x00FF00)
SendMessage(hce SCI.SCI_INDICSETSTYLE indicator SCI.INDIC_STRAIGHTBOX)
SendMessage(hce SCI.SCI_INDICSETUNDER indicator TRUE)
int line=SendMessage(hce SCI.SCI_LINEFROMPOSITION curPos 0)
int lep=SendMessage(hce SCI.SCI_GETLINEENDPOSITION line 0)
act hce
rep 4
,SendMessage(hce SCI.SCI_INDICATORFILLRANGE curPos lep-curPos)
,0.25
,SendMessage(hce SCI.SCI_INDICATORCLEARRANGE curPos lep-curPos)
,0.25
SendMessage(hce SCI.SCI_SETINDICATORCURRENT 0 0)
#19
@Kevin
wow!  thank you!!
All the features have been implemented and work well!
#20
I want to use , and . to select an item, use / close, but it has no effect
 
Code:
Copy      Help
,case WM_CHAR
,sel(wParam)
,,case 44 ;;Press ,
,,key D
,,ret
,,case 46 ;;Press .
,,key U
,,ret
,,case 47 ;;Press / close
,,clo
,,ret
#21
Function DynamicLV
Code:
Copy      Help
;/
function# str'text [flags];;optional .1 show dialog at caret position if possible. 0 or omitted show dialog at center of screen(default)

int iid to=Statement(1 0 0 iid)
str ss.getmacro(iid)
ss.left(ss to)
if(flags&1)
,int xx yy isCaret
,isCaret = GetCaretXY(xx yy)
str dd=
;BEGIN DIALOG
;0 "" 0x90080AC8 0x0 0 0 184 108 "Dialog"
;3 SysListView32 0x5403C04D 0x204 0 0 184 108 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040C00 "*" "" "" ""

int iii= ShowDialog(dd &sub.DlgProc 0)
ret iii

#sub DlgProc v
function# hDlg message wParam lParam

int hsys32=id(3 hDlg)
sel message
,case WM_INITDIALOG
,__Font- f.CreateNew(hsys32 "Microsoft YaHei Mono" 11) ;;change this
,f.SetDialogFont(hDlg "3")
,int es=LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_GRIDLINES
,SendMessage hsys32 LVM_SETEXTENDEDLISTVIEWSTYLE es es
,TO_LvAddCol hsys32 0 "" -90
,TO_LvAddCol hsys32 1 "" -10
;,Fill-in values to sys32
,int n=numlines(text)
,for int'i 0 n
,,_s.getl(text i)
,,TO_LvAdd hsys32 i 0 0 _s i+1
,RECT r.left=LVIR_BOUNDS; SendMessage(hsys32 LVM_GETITEMRECT 0 &r)
,int xy=SendMessage(hsys32 LVM_APPROXIMATEVIEWRECT n -1|-1)
,int width = xy & 0x0000FFFF
,int hh = xy>>16&0x0000FFFF
,siz width+4 hh hsys32
,siz width+11 hh-r.bottom+8 hDlg
,sub.LvSelect hsys32 0
,if(isCaret > 0) ;; if caret is found  and flag is 1 move dialog to caret
,,mov xx yy+25 hDlg
,case WM_DESTROY
,case WM_COMMAND goto messages2
,case WM_NOTIFY goto messages3
ret
;messages2
sel wParam
,case IDOK
,int ii=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,DT_EndDialog(hDlg ii)
,case IDCANCEL
,DT_EndDialog(hDlg 1000);;;return this to know dialog was closed  using alt+F4 or esc
ret 1
;messages3
NMHDR* nh=+lParam
sel nh.idFrom
,case 3
,sel nh.code
,,case LVN_KEYDOWN
,,NMLVKEYDOWN* lvk=+nh
,,if lvk.wVKey=188 or lvk.wVKey=190 or lvk.wVKey=191
,,,if lvk.wVKey=188
,,,,sub.SendKey(nh.hwndFrom VK_DOWN)
,,,,ret
,,,if lvk.wVKey=190
,,,,sub.SendKey(nh.hwndFrom VK_UP)
,,,,ret
,,,if lvk.wVKey=191
,,,,DT_EndDialog(hDlg 1000)
,,for i 0 numlines(text)
,,,_s.getl(text i)
,,,if(_s[0] = lvk.wVKey)
,,,,DT_EndDialog(hDlg i)
,,,,break
,,case NM_DBLCLK;;on double left click of listview item
,,i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,,DT_EndDialog(hDlg i)
,,case NM_RCLICK;;on right click of listview item
,,i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,,str lviText.getl(text i)
,,DT_EndDialog(hDlg 1000)
,,int posF=find(ss lviText 0)
,,sub.FlashCodeLine(posF iid)
#sub LvSelect
function hlv item [flags] ;;flags: 1 don't deselect previous, 2 don't set focus, 4 ensure visible, 8 deselect

;Selects listview item.
;To select none, use item -1.
;To select all, use item -1 and flag 8.
;Note that listview controls with LVS_SINGLESEL style can have max 1 item selected.

LVITEMW li.stateMask=LVIS_FOCUSED|LVIS_SELECTED
if(item>=0)
,if(flags&9=0) SendMessage hlv LVM_SETITEMSTATE -1 &li
,if(flags&8=0) li.state=LVIS_SELECTED; if(flags&2=0) li.state|LVIS_FOCUSED
,SendMessage hlv LVM_SETITEMSTATE item &li
,if(flags&4) SendMessage hlv LVM_ENSUREVISIBLE item 0
else
,if(flags&8) li.state=LVIS_SELECTED
,SendMessage hlv LVM_SETITEMSTATE -1 &li
,
#sub FlashCodeLine
function curPos iid [hce]
if(!hce) hce=GetQmCodeEditor
mac+ iid
act hce
SendMessage hce SCI.SCI_GOTOPOS curPos 0
int indicator=19
SendMessage(hce SCI.SCI_SETINDICATORCURRENT indicator 0)
SendMessage(hce SCI.SCI_INDICSETALPHA indicator 100)
SendMessage(hce SCI.SCI_INDICSETFORE indicator 0x00FF00)
SendMessage(hce SCI.SCI_INDICSETSTYLE indicator SCI.INDIC_STRAIGHTBOX)
SendMessage(hce SCI.SCI_INDICSETUNDER indicator TRUE)
int line=SendMessage(hce SCI.SCI_LINEFROMPOSITION curPos 0)
int lep=SendMessage(hce SCI.SCI_GETLINEENDPOSITION line 0)
act hce
rep 4
,SendMessage(hce SCI.SCI_INDICATORFILLRANGE curPos lep-curPos)
,0.25
,SendMessage(hce SCI.SCI_INDICATORCLEARRANGE curPos lep-curPos)
,0.25
SendMessage(hce SCI.SCI_SETINDICATORCURRENT 0 0)

#sub SendKey
function hwnd vk [flags] ;;flags: 0 down-up, 1 down, 2 up

;Posts keyboard messages directly to a control. The window can be inactive.
;You can find virtual-key codes in QM help. For alphanumeric keys, use uppercase characters in '', eg 'A'.

;hwnd - control handle.
;vk - virtual-key code.

int m1 m2 lp=MapVirtualKey(vk 0)<<16|1
sel(vk) case [3,33,34,35,36,37,38,39,40,44,45,46,91,92,93,111,144,VK_RCONTROL,VK_RMENU] lp|0x1000000 ;;ek
if(flags&3!2) PostMessage hwnd WM_KEYDOWN vk lp
if(flags&3!1) PostMessage hwnd WM_KEYUP vk lp|0xC0000000
#22
Press the key   ,   .   an alert sound will be emitted, Using the up and down keys directly will not

addition, I want to press the Tab key, which can confirm the selection
#23
sorry i had sounds off didn't catch it. Will need to eat those keys so probably best to use this

Function DynamicLVKeys
Trigger !v"Dialog_DLV" "#32770"     Help - how to add the trigger to the macro
 
Code:
Copy      Help
int hwnd=TriggerWindow
int- hlv=child("" "SysListView32" hwnd)
int hh=SetWindowsHookEx(WH_KEYBOARD_LL &sub.Hook_WH_KEYBOARD_LL _hinst 0)
opt waitmsg 1
rep
,0.2 -WV hlv
,err
,,continue
,break
UnhookWindowsHookEx hh

#sub Hook_WH_KEYBOARD_LL
function# nCode message KBDLLHOOKSTRUCT&k
if(nCode<0) goto gNext
int- hlv
int isActive=hlv
if(!isActive) SendMessage hlv WM_ACTIVATE WA_ACTIVE 0
int up=k.flags&LLKHF_UP
FormatKeyString k.vkCode 0 &_s;
if _s=","
,if(!up)
,,SendKeysToWindow2(hlv key(D))
,ret 1
if _s="."    
,if(!up)
,,SendKeysToWindow2(hlv key(U))    
,ret 1
if _s="/"    
,if(!up)
,,SendKeysToWindow2(hlv key(Z))    
,ret 1    
if _s="Tab"    
,,if(!up)
,,,SendKeysToWindow2(hlv key(Y))    
,,ret 1    
;gNext
ret CallNextHookEx(0 nCode message &k)

Function DynamicLV
 
Code:
Copy      Help
;/
function# str'text [flags];;optional .1 show dialog at caret position if possible. 0 or omitted show dialog at center of screen(default)

int iid to=Statement(1 0 0 iid)
str ss.getmacro(iid)
ss.left(ss to)
if(flags&1)
,int xx yy isCaret
,isCaret = GetCaretXY(xx yy)
str dd=
;BEGIN DIALOG
;0 "" 0x90080AC8 0x0 0 0 184 108 "Dialog_DLV"
;3 SysListView32 0x5403C04D 0x204 0 0 184 108 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040C00 "*" "" "" ""

int iii= ShowDialog(dd &sub.DlgProc 0)
ret iii

#sub DlgProc v
function# hDlg message wParam lParam

int hsys32=id(3 hDlg)
sel message
,case WM_INITDIALOG
,__Font- f.CreateNew(hsys32 "Microsoft YaHei Mono" 11) ;;change this
,f.SetDialogFont(hDlg "3")
,int es=LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_GRIDLINES
,SendMessage hsys32 LVM_SETEXTENDEDLISTVIEWSTYLE es es
,TO_LvAddCol hsys32 0 "" -90
,TO_LvAddCol hsys32 1 "" -10
;,Fill-in values to sys32
,int n=numlines(text)
,for int'i 0 n
,,_s.getl(text i)
,,TO_LvAdd hsys32 i 0 0 _s i+1
,RECT r.left=LVIR_BOUNDS; SendMessage(hsys32 LVM_GETITEMRECT 0 &r)
,int xy=SendMessage(hsys32 LVM_APPROXIMATEVIEWRECT n -1|-1)
,int width = xy & 0x0000FFFF
,int hh = xy>>16&0x0000FFFF
,siz width+4 hh hsys32
,siz width+11 hh-r.bottom+8 hDlg
,sub.LvSelect hsys32 0
,if(isCaret > 0) ;; if caret is found  and flag is 1 move dialog to caret
,,mov xx yy+25 hDlg
,case WM_DESTROY
,case WM_COMMAND goto messages2
,case WM_NOTIFY goto messages3
ret
;messages2
sel wParam
,case IDOK
,int ii=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,DT_EndDialog(hDlg ii)
,case IDCANCEL
,DT_EndDialog(hDlg 1000);;;return this to know dialog was closed  using alt+F4 or esc
ret 1
;messages3
NMHDR* nh=+lParam
sel nh.idFrom
,case 3
,sel nh.code
,,case LVN_KEYDOWN
,,NMLVKEYDOWN* lvk=+nh
,,for i 0 numlines(text)
,,,_s.getl(text i)
,,,if(_s[0] = lvk.wVKey)
,,,,DT_EndDialog(hDlg i)
,,,,break
,,case NM_DBLCLK;;on double left click of listview item
,,i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,,DT_EndDialog(hDlg i)
,,case NM_RCLICK;;on right click of listview item
,,i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,,str lviText.getl(text i)
,,DT_EndDialog(hDlg 1000)
,,int posF=find(ss lviText 0)
,,sub.FlashCodeLine(posF iid)
#sub LvSelect
function hlv item [flags] ;;flags: 1 don't deselect previous, 2 don't set focus, 4 ensure visible, 8 deselect

;Selects listview item.
;To select none, use item -1.
;To select all, use item -1 and flag 8.
;Note that listview controls with LVS_SINGLESEL style can have max 1 item selected.

LVITEMW li.stateMask=LVIS_FOCUSED|LVIS_SELECTED
if(item>=0)
,if(flags&9=0) SendMessage hlv LVM_SETITEMSTATE -1 &li
,if(flags&8=0) li.state=LVIS_SELECTED; if(flags&2=0) li.state|LVIS_FOCUSED
,SendMessage hlv LVM_SETITEMSTATE item &li
,if(flags&4) SendMessage hlv LVM_ENSUREVISIBLE item 0
else
,if(flags&8) li.state=LVIS_SELECTED
,SendMessage hlv LVM_SETITEMSTATE -1 &li
,
#sub FlashCodeLine
function curPos iid [hce]
if(!hce) hce=GetQmCodeEditor
mac+ iid
act hce
SendMessage hce SCI.SCI_GOTOPOS curPos 0
int indicator=19
SendMessage(hce SCI.SCI_SETINDICATORCURRENT indicator 0)
SendMessage(hce SCI.SCI_INDICSETALPHA indicator 100)
SendMessage(hce SCI.SCI_INDICSETFORE indicator 0x00FF00)
SendMessage(hce SCI.SCI_INDICSETSTYLE indicator SCI.INDIC_STRAIGHTBOX)
SendMessage(hce SCI.SCI_INDICSETUNDER indicator TRUE)
int line=SendMessage(hce SCI.SCI_LINEFROMPOSITION curPos 0)
int lep=SendMessage(hce SCI.SCI_GETLINEENDPOSITION line 0)
act hce
rep 4
,SendMessage(hce SCI.SCI_INDICATORFILLRANGE curPos lep-curPos)
,0.25
,SendMessage(hce SCI.SCI_INDICATORCLEARRANGE curPos lep-curPos)
,0.25
SendMessage(hce SCI.SCI_SETINDICATORCURRENT 0 0)
#24
thanks, the code Works well!

But there is one place where it is not perfect, such as the following example:

There are two lines that begin with the letter B

When I press the B key, only the first item is output directly

So, I want to pick the first item that starts with the letter B, Press the B key again to move to the second item, At this point, I can also use , and . Select them

But, If the letter at the begin of a line is unique, when I press the letter, the item is output directly, such as the A, C, E in the example

This can be a bit complicated to implement  Smile

Autotext Autotext
Trigger $t     Help - how to add the trigger to the macro
Code:
Copy      Help
/b/i/c/m
te :sub.Sub1 ;;1 test DynamicLV

#sub Sub1 m
_s=
;A  I'm in the line A
;B  I'm in the line B1
;B  I'm in the line B2
;C  I'm in the line C
;D  I'm in the line D1
;D  I'm in the line D2
;E  I'm in the line E
;F  I'm in the line F1
;F  I'm in the line F2

_i=DynamicLV(_s 1)
if _i=1000
,ret;; end if alt+f4 or esc was used to closed dialog
str ss
ss.getl(_s _i)
mes ss
#25
this covers that
Function DynamicLV
Code:
Copy      Help
;/
function# str'text [flags];;optional .1 show dialog at caret position if possible. 0 or omitted show dialog at center of screen(default)

int iid to=Statement(1 0 0 iid)
str ss.getmacro(iid)
ss.left(ss to)
if(flags&1)
,int xx yy isCaret
,isCaret = GetCaretXY(xx yy)
str dd=
;BEGIN DIALOG
;0 "" 0x90080AC8 0x0 0 0 184 108 ""
;3 SysListView32 0x5403C04D 0x204 0 0 184 108 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040C00 "*" "" "" ""

int iii= ShowDialog(dd &sub.DlgProc 0)
ret iii

#sub DlgProc v
function# hDlg message wParam lParam

int hsys32=id(3 hDlg)
sel message
,case WM_INITDIALOG
,__Font- f.CreateNew(hsys32 "Segoe UI" 12) ;;change this
,f.SetDialogFont(hDlg "3")
,int es=LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_GRIDLINES
,SendMessage hsys32 LVM_SETEXTENDEDLISTVIEWSTYLE es es
,TO_LvAddCol hsys32 0 "" -90
,TO_LvAddCol hsys32 1 "" -10
;,Fill-in values to sys32
,int n=numlines(text)
,for int'i 0 n
,,_s.getl(text i)
,,TO_LvAdd hsys32 i 0 0 _s i+1
,RECT r.left=LVIR_BOUNDS; SendMessage(hsys32 LVM_GETITEMRECT 0 &r)
,int xy=SendMessage(hsys32 LVM_APPROXIMATEVIEWRECT n -1|-1)
,int width = xy & 0x0000FFFF
,int hh = xy>>16&0x0000FFFF
,siz width+4 hh hsys32
,siz width+11 hh-r.bottom+8 hDlg
,sub.LvSelect hsys32 0
,if(isCaret > 0) ;; if caret is found  and flag is 1 move dialog to caret
,,mov xx yy+25 hDlg
,case WM_DESTROY
,case WM_COMMAND goto messages2
,case WM_NOTIFY goto messages3
ret
;messages2
sel wParam
,case IDOK
,int ii=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,DT_EndDialog(hDlg ii)
,case IDCANCEL
,DT_EndDialog(hDlg 1000);;;return this to know dialog was closed  using alt+F4 or esc
ret 1
;messages3
NMHDR* nh=+lParam
sel nh.idFrom
,case 3
,sel nh.code
,,case LVN_KEYDOWN
,,NMLVKEYDOWN* lvk=+nh
,,if(lvk.wVKey<64 or lvk.wVKey>91)
,,,ret
,,int ln dc=sub.CheckForUnique(text lvk.wVKey ln)
,,if dc=0
,,,DT_EndDialog(hDlg ln)
,,case NM_DBLCLK;;on double left click of listview item
,,i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,,DT_EndDialog(hDlg i)
,,case NM_RCLICK;;on right click of listview item
,,i=SendDlgItemMessage(hDlg 3 LVM_GETNEXTITEM -1 LVNI_SELECTED)
,,str lviText2
,,GetListViewItemText nh.hwndFrom i-1 lviText2 0 2
,,str lviText.getl(text i)
,,DT_EndDialog(hDlg 1000)
,,int posF=find(ss lviText 0)
,,sub.FlashCodeLine(posF iid)
#sub LvSelect
function hlv item [flags] ;;flags: 1 don't deselect previous, 2 don't set focus, 4 ensure visible, 8 deselect

;Selects listview item.
;To select none, use item -1.
;To select all, use item -1 and flag 8.
;Note that listview controls with LVS_SINGLESEL style can have max 1 item selected.

LVITEMW li.stateMask=LVIS_FOCUSED|LVIS_SELECTED
if(item>=0)
,if(flags&9=0) SendMessage hlv LVM_SETITEMSTATE -1 &li
,if(flags&8=0) li.state=LVIS_SELECTED; if(flags&2=0) li.state|LVIS_FOCUSED
,SendMessage hlv LVM_SETITEMSTATE item &li
,if(flags&4) SendMessage hlv LVM_ENSUREVISIBLE item 0
else
,if(flags&8) li.state=LVIS_SELECTED
,SendMessage hlv LVM_SETITEMSTATE -1 &li
,
#sub FlashCodeLine
function curPos iid [hce]
if(!hce) hce=GetQmCodeEditor
mac+ iid
act hce
SendMessage hce SCI.SCI_GOTOPOS curPos 0
int indicator=19
SendMessage(hce SCI.SCI_SETINDICATORCURRENT indicator 0)
SendMessage(hce SCI.SCI_INDICSETALPHA indicator 100)
SendMessage(hce SCI.SCI_INDICSETFORE indicator 0x00FF00)
SendMessage(hce SCI.SCI_INDICSETSTYLE indicator SCI.INDIC_STRAIGHTBOX)
SendMessage(hce SCI.SCI_INDICSETUNDER indicator TRUE)
int line=SendMessage(hce SCI.SCI_LINEFROMPOSITION curPos 0)
int lep=SendMessage(hce SCI.SCI_GETLINEENDPOSITION line 0)
act hce
rep 4
,SendMessage(hce SCI.SCI_INDICATORFILLRANGE curPos lep-curPos)
,0.25
,SendMessage(hce SCI.SCI_INDICATORCLEARRANGE curPos lep-curPos)
,0.25
SendMessage(hce SCI.SCI_SETINDICATORCURRENT 0 0)

#sub CheckForUnique
function ~text keys &ln
int count
for _i 0 numlines(text)
,_s.getl(text _i)
,if(_s[0] = keys)
,,ln=_i
,,count+1
if(count >1) ret 1; else ret
#26
@Kevin 

I want the DynamicLV window to be centered relative to the currently open window, When the text cursor cannot be found, such as in PowerShell ISE

I have the code below, but it doesn't work

Macro Macro3
Code:
Copy      Help
int w=win("" "#32770")
RECT r; DpiGetWindowRect w &r

int wL=hwnd
int cx cy
GetWinXY wL 0 0 cx cy

int x = r.left + ((r.right - r.left - cx)/2)
int y = r.top + ((r.bottom - r.top - cy)/2)

mov x y wL
#27
before 
 
Code:
Copy      Help
int iid to=Statement(1 0 0 iid)

add
 
Code:
Copy      Help
int w1=win()
RECT r1; DpiGetWindowRect w1 &r1

after
 
Code:
Copy      Help
,if(isCaret > 0) ;; if caret is found  and flag is 1 move dialog to caret
,,mov xx yy+25 hDlg

add
Code:
Copy      Help
,else
,,int Dwidth Dheight
,,GetWinXY hDlg 0 0 Dwidth Dheight
,,int Dx = r1.left + ((r1.right - r1.left - Dwidth)/2)
,,int Dy = r1.top + ((r1.bottom - r1.top - Dheight)/2)
,,mov Dx Dy hDlg
#28
@Kevin
worked well, Thank you
#29
@Kevin
 Switching from F to D sometimes does not respond and requires waiting a while
 Not sensitive enough

[Image: abc.gif]

Autotext AT1
Trigger $t     Help - how to add the trigger to the macro
Code:
Copy      Help
/b/i/c/m
te :sub.Sub1 ;;1 test DynamicLV

#sub Sub1 m
_s=
;A  I'm in the line A
;B  I'm in the line B1
;B  I'm in the line B2
;C  I'm in the line C
;D  I'm in the line D1
;D  I'm in the line D2
;E  I'm in the line E
;F  I'm in the line F1
;F  I'm in the line F2

_i=DynamicLV(_s 1)
if _i=1000
,ret;; end if alt+f4 or esc was used to closed dialog
str ss
ss.getl(_s _i)
mes ss
#30
This feature is useful and can be used for classification


Forum Jump:


Users browsing this thread: 1 Guest(s)