Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Executes subfunctions within AutoText files by searching for comments
#1
Hi,

In the following example, some subfunctions have "one" or "two" in their comments
I want to find them by searching and then execute the subfunction of the selected item

I wrote the following code, but there are still three features that are not implemented

For better expression, I recorded the demo in the picture below
[Image: ab.gif]

Thanks in advance for any advice and help
david



Function Notepad_Dialog
Trigger Aw //Notepad_FF     Help - how to add the trigger to the macro
Code:
Copy      Help
;Note:
;When Notepad window opens, pressing hotkey Alt+W will popping up this dialog, Because it uses a filter function Notepad_FF

;Todo1:
;There are also two AutoText files use filter function Notepad_FF, Notepad_1 and Notepad_2, get all the items inside them
;Tip: In actual use, need to get all items in AutoText files that uses the same filtering function as the dialog
;The following code only gets the items in the Notepad_1 file, How to get another?(uses same filtering function as the dialog)

str name="Notepad_1"
str at=sub.atList(name)

ARRAY(str) aList=at
IQmDropdown ddl
int inERS

str dd=
;BEGIN DIALOG
;0 "" 0x90C80AC8 0x8 0 0 184 16 "Notepad_AutoText" "4"
;3 Edit 0x54030080 0x200 0 0 184 16 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040C02 "*" "" "" ""

str controls = "3"
str e3
if(!ShowDialog(dd &sub.DlgProc &controls)) ret

#sub DlgProc
function# hDlg message wParam lParam

sel message
,case WM_INITDIALOG
,;Todo2:
,;How to temporarily disable AutoText files except AT1 (because AT1 use global trigger $t)
,;to prevent others AutoText list popping up when typing
,;In this example, the files that should be disabled are: AT2, Notepad_1, Notepad_2 (They not use global trigger $t)
,
,__Font-- f.Create("Consolas" 14 0)
,f.SetDialogFont(hDlg "3")
,case WM_DESTROY
,case WM_COMMAND goto messages2
ret
;messages2
sel wParam
,case IDOK
,;Todo3
,;How to execute the selected item's subfunction when the dialog box is closed
,
,case IDCANCEL
,
,case EN_CHANGE<<16|3 sub.OnTextChanged lParam
ret 1

#sub atList
function~ str'name

str pattern="(?m)(^.+) :sub.Sub\d+ ;;(.+)"
_s.getmacro(name 0)
str d
int i
ARRAY(str) a
findrx(_s pattern 0 4 a)
for i 0 a.len
,d.formata("%s - %s[]" a[1 i].trim a[2 i].trim)
ret d

#sub OnTextChanged v
function hEdit

if(inERS) ret
if(ddl) ddl.Close; ddl=0

str s.getwintext(hEdit)
if(!s.len) ret

ICsv x._create
x.AddRow1(0 "")
int i
for i 0 aList.len
,if(find(aList[i] s 0 1)<0) continue
,x.AddRow1(-1 aList[i])
if(!x.RowCount) ret

if(ShowDropdownList(x i 0 1 hEdit 0 0 0 ddl)&QMDDRET_SELOK=0) ret
s=x.Cell(i+1 0)

inERS=1
EditReplaceSel hEdit 0 s 1
inERS=0


Attached Files
.qml   Notepad.qml (Size: 7 KB / Downloads: 158)
#2
for todo1

at beginning place this
 
Code:
Copy      Help
QMITEM q q1
int ii i=qmitem(getopt(itemname 0) 1 &q 1|32)
str filterName= q.filter
ARRAY(str) atn
rep
,ii=qmitem(-ii 1|16 &q1 1|32)
,if(ii=0) break
,if q1.itype=4
,,if q1.filter=filterName
,,,atn[]=q1.name
str name=atn; name.rtrim
str at=sub.atList(name)

change sub.atList to
Code:
Copy      Help
function~ str'name

str pattern="(?m)(^.+) :sub.Sub\d+ ;;(.+)"
str d ss
int i
ARRAY(str) a
foreach ss name
,_s.getmacro(ss 0)
,findrx(_s pattern 0 4 a)
,for i 0 a.len
,,d.formata("%s - %s[]" a[1 i].trim a[2 i].trim)
ret d.rtrim

for Todo3
you cannot call autotext code from other macros or functions
#3
thanks

for Todo3:
I thought of a way, 
Get the text of the subfunction first, then use function RunTextAsMacro, but it can be a bit complicated

for Todo2:
I found a piece of code on the forum, but it may need to be modified
 
Code:
Copy      Help
#sub DisableEnableAutoText
function mode [str'dati] [str&atItems] [str&atditems]
QMITEM q; int i
ARRAY(str) atn atd
rep
,i=qmitem(-i 1|16 &q 1)
,if(i=0) break
,if q.itype=4
,,atn[]=q.name
,,sel mode
,,,case 1 ;;disable
,,,if(dis(q.name)) atd[]=q.name
,,,else dis+ q.name
,,,case else ;;enable
,,,int fdat=findw(dati q.name 0 "[]")
,,,if fdat = -1
,,,,dis- q.name
if(mode <>1) ret
atn.sort(8)
atItems=atn
atditems=atd

The following can execute the code for sub.Sub1

Macro Macro1
Code:
Copy      Help
_s=
;/b/i/c/m
;aa :sub.Sub1 ;;1 one a
;bb :sub.Sub2 ;;2 one b
;cc :sub.Sub3 ;;3 two c
;dd :sub.Sub4 ;;4 two d
;
;#sub Sub1 m
;"one a"
;
;#sub Sub2 m
;"one b"
;
;#sub Sub3 m
;"two c"
;
;#sub Sub4 m
;"two d"

ARRAY(str) a
findrx(_s "(?s)#sub Sub1 m(.+?)#sub Sub" 0 1 a)

;out a[1].trim
RunTextAsMacro a[1].trim
#4
This is a very useful feature, Because, sometimes abbreviations can get forgotten,
After pressing the space bar, all the items can be displayed, and search items by abbreviations and comments are supported
But executing the code in the subfunctions is a challenge

[Image: ab.gif]
#5
I came up with a simple way(Simulate input abbreviations) to do this, but Abbreviations are not replaced with actual text

if(!ShowDialog(dd &sub.DlgProc &controls)) ret
e3.replacerx(" - .+")
opt slowkeys; spe 300
key F"{e3}" T

[Image: ab.gif]
#6
Function Notepad_Dialog
Trigger Aw //Notepad_FF     Help - how to add the trigger to the macro
Code:
Copy      Help
str- sItems
str- sdItems
sub.DisableEnableAutoText(1 "" sItems sdItems)
QMITEM q q1
int ii i=qmitem(getopt(itemname 0) 1 &q 1|32)
str filterName= q.filter
ARRAY(str) atn
rep
,ii=qmitem(-ii 1|16 &q1 1|32)
,if(ii=0) break
,if q1.itype=4
,,if q1.filter=filterName
,,,atn[]=q1.name
str names=atn; names.rtrim
str at=sub.atList(names)
ARRAY(str) aList=at
IQmDropdown ddl
int inERS

str dd=
;BEGIN DIALOG
;0 "" 0x90C80AC8 0x8 0 0 184 16 "Notepad_AutoText" "4"
;3 Edit 0x54030080 0x200 0 0 184 16 ""
;END DIALOG
;DIALOG EDITOR: "" 0x2040C02 "*" "" "" ""

str controls = "3"
str e3
if(!ShowDialog(dd &sub.DlgProc &controls)) ret
str textEnd subNum a ss
findrx(e3 "\-\s\d+\s(.*)$" 0 1 textEnd 1)
findrx(e3 "\-\s(\d+)" 0 1 subNum 1)
int subn=val(subNum)
foreach ss names
,_s.getmacro(ss)
,findrx(_s F"(?s)#sub Sub{subn} m(.+?)#sub Sub" 0 1 a 1)
,if !a.len
,,findrx(_s F"(?s)#sub Sub{subn} m(.*)$" 0 1 a 1)
,if a=textEnd
,,break
if(a.len)
,RunTextAsMacro a.trim
else
,out "not Found"

#sub DlgProc
function# hDlg message wParam lParam
str- sItems
str- sdItems
sel message
,case WM_INITDIALOG
,__Font-- f.Create("Consolas" 14 0)
,f.SetDialogFont(hDlg "3")
,str- selected
,case WM_DESTROY
,case WM_COMMAND goto messages2
ret
;messages2
sel wParam
,case IDOK
,sub.DisableEnableAutoText(2 sdItems)
,case IDCANCEL
,sub.DisableEnableAutoText(3 sdItems)
,case EN_CHANGE<<16|3 sub.OnTextChanged lParam
ret 1

#sub atList
function~ str'name

str pattern="(?m)(^.+) :sub.Sub\d+ ;;(.+)"
str d ss
int i
ARRAY(str) a
foreach ss name
,_s.getmacro(ss 0)
,findrx(_s pattern 0 4 a)
,for i 0 a.len
,,d.formata("%s - %s[]" a[1 i].trim a[2 i].trim)
ret d.rtrim

#sub OnTextChanged v
function hEdit

if(inERS) ret
if(ddl) ddl.Close; ddl=0
str s.getwintext(hEdit)
if(!s.len) ret
ICsv x._create
x.AddRow1(0 "")
int i
for i 0 aList.len
,if(find(aList[i] s 0 1)<0) continue
,x.AddRow1(-1 aList[i])
if(!x.RowCount) ret
if(ShowDropdownList(x i 0 1 hEdit 0 0 0 ddl)&QMDDRET_SELOK=0) ret
s=x.Cell(i+1 0)
inERS=1
EditReplaceSel hEdit 0 s 1|2|4
inERS=0

#sub DisableEnableAutoText
function mode [str'dati] [str&atItems] [str&atditems]
QMITEM q; int i j k
ARRAY(str) atn atd
rep
,i=qmitem(-i 1|16 &q 1|4|32)
,if(i=0) break
,if q.itype=4
,,atn[]=q.name
,,sel mode
,,,case 1
,,,if(dis(q.name))
,,,,atd[]=q.name
,,,else
,,,,if(q.programs or q.filter)
,,,,,dis+ q.name
,,,case else
,,,int fdat=findw(dati q.name 0 "[]")
,,,if fdat = -1
,,,,dis- q.name
#7
@Kevin
thank you so much, Your programming level is fantastic!

I want to continue refining the subfunction OnTextChanged
1.How to make the first item always selected?(Same as AutoText list)
2.After selecting the item, press enter, directly execute(Automatically closes the dialog), no need to press enter key again
3.Press the right mouse button on the item to locate the position of the subfunction and flash it
#8
I found most of the code in the post below, But I don't know how to get the handle to the control SysListView32

https://www.quickmacros.com/forum/showth...9#pid36089

#1.How to make the first item always selected?(Same as AutoText list)
 
Code:
Copy      Help
sub.LvSelect hsys32 0

#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


#3.Press the right mouse button on the item to locate the position of the subfunction and flash it
 
Code:
Copy      Help
,case WM_NOTIFY goto messages3
;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 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)
#9
for #1 find
x.AddRow1(0 "")
 Change to
x.AddRow1(0 "0")
#10
for #2 succeeded

    case EN_CHANGE<<16|3 sub.OnTextChanged lParam hDlg
 
Code:
Copy      Help
#sub OnTextChanged v
function hEdit hDlg

if(inERS) ret
if(ddl) ddl.Close; ddl=0
str s.getwintext(hEdit)
if(!s.len) ret
ICsv x._create
x.AddRow1(0 "0")
int i
for i 0 aList.len
,if(find(aList[i] s 0 1)<0) continue
,x.AddRow1(-1 aList[i])
if(!x.RowCount) ret
if(ShowDropdownList(x i 0 1 hEdit 0 0 0 ddl)&QMDDRET_SELOK=0) ret
s=x.Cell(i+1 0)
inERS=1
EditReplaceSel hEdit 0 s 1|2|4
DT_Ok hDlg
sub.DisableEnableAutoText(2 sdItems)
inERS=0

for #3 
It's a bit complicated
#11
3.Press the right mouse button on the item to locate the position of the subfunction and flash it

How to create an event(Right-click) for an item in a drop-down list?
#12
In #sub OnTextChanged instead of using 

DT_Ok hDlg
sub.DisableEnableAutoText(2 sdItems)


change to this
Code:
Copy      Help
SendMessage(GetParent(hEdit) WM_COMMAND IDOK 0)
#13
good way
thank you so much


Forum Jump:


Users browsing this thread: 3 Guest(s)