-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathTVFind.asm
320 lines (243 loc) · 9.22 KB
/
TVFind.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
TreeViewFindItemBranch PROTO :DWORD, :DWORD, :DWORD
TreeViewFindTextCheckString PROTO :DWORD, :DWORD, :DWORD
TreeViewFindItemInString PROTO :DWORD, :DWORD, :DWORD
.DATA
szTreeViewFindItemText DB MAX_PATH DUP (0)
szTextViewFindSearchText DB MAX_PATH DUP (0)
; do master loop calling to iterate child/next branches, if not found, then do another loop, getparent, check, if not get parents next, if not 0 do mini loop again.
.code
;**************************************************************************
; TreeViewFindItem - count child items under current item,
; if bRecurse is TRUE then it will count all grandchildren etc as well
;**************************************************************************
TreeViewFindItem PROC hTreeview:DWORD, hItem:DWORD, lpszFindText:DWORD
LOCAL hCurrentItem:DWORD
LOCAL hFoundItem:DWORD
;PrintText '----------------------'
;PrintText 'TreeViewFindItem'
;PrintDec hTreeview
;PrintDec hItem
;PrintDec lpszFindText
;PrintText '----------------------'
.IF hTreeview == NULL || lpszFindText == NULL
mov eax, 0
ret
.ENDIF
Invoke lstrlen, lpszFindText
.IF eax == 0
mov eax, 0
ret
.ENDIF
Invoke lstrcpy, Addr szTextViewFindSearchText, lpszFindText
;Invoke szUpper, Addr szTextViewFindSearchText
mov hFoundItem, 0
.IF hItem == NULL
;Invoke TreeViewGetSelectedItem, hTreeview
Invoke SendMessage, hTreeview, TVM_GETNEXTITEM, TVGN_ROOT, NULL
.ELSE
mov eax, hItem
.ENDIF
mov hCurrentItem, eax
.WHILE eax != NULL
mov hCurrentItem, eax
Invoke TreeViewFindItemBranch, hTreeview, hCurrentItem, Addr szTextViewFindSearchText ;lpszFindText
mov hFoundItem, eax
.IF hFoundItem != 0
;PrintText 'found match in TreeViewFindItemBranch'
;.BREAK ; found our item so break out of loop
mov eax, hFoundItem
.BREAK
.ENDIF
;PrintText 'no match found in TreeViewFindItemBranch, start looping up parent/next'
mov eax, hCurrentItem
.WHILE eax != NULL
;PrintText 'Looking for next sibling'
Invoke SendMessage, hTreeview, TVM_GETNEXTITEM, TVGN_NEXT, hCurrentItem
.IF eax != NULL ; current item has a sibling, so go check that
mov hCurrentItem, eax
Invoke TreeViewFindTextCheckString, hTreeview, hCurrentItem, lpszFindText
.IF eax == TRUE
mov eax, hCurrentItem
mov hFoundItem, eax
.BREAK
.ENDIF
;Invoke TreeViewGetItemText, hTreeview, hCurrentItem, Addr szSelectedTreeviewText, SIZEOF szSelectedTreeviewText
;PrintString szSelectedTreeviewText
mov eax, hCurrentItem
mov hFoundItem, 0
.BREAK
.ELSE
;PrintText 'Looking for parent of item'
Invoke SendMessage, hTreeview, TVM_GETNEXTITEM, TVGN_PARENT, hCurrentItem
.IF eax != NULL ; current item has no sibling so we goto parent, check that first
mov hCurrentItem, eax
mov eax, hCurrentItem
mov hFoundItem, 0
.CONTINUE ; didnt find our item in parent, so get parents sibling to check for
.ELSE ; top parent, no more parents to check so return 0
;PrintText 'no more parents to check'
mov eax, NULL
mov hFoundItem, 0
.BREAK
.ENDIF
.ENDIF
; eax contains next sibling to check for or null (no sibling)
.ENDW
.IF hFoundItem != 0
.BREAK ; found our item so break out of loop
.ENDIF
.ENDW
;PrintDec hFoundItem
mov eax, hFoundItem
ret
TreeViewFindItem ENDP
;**************************************************************************
; Finds text from current node down the current branch - all children under
; this node and their children
;**************************************************************************
TreeViewFindItemBranch PROC hTreeview:DWORD, hItem:DWORD, lpszFindText:DWORD
LOCAL hCurrentItem:DWORD
LOCAL hFoundItem:DWORD
mov hFoundItem, 0
.IF hItem == NULL
;Invoke TreeViewGetSelectedItem, hTreeview
Invoke SendMessage, hTreeview, TVM_GETNEXTITEM, TVGN_ROOT, NULL
.ELSE
mov eax, hItem
.ENDIF
mov hCurrentItem, eax
Invoke SendMessage, hTreeview, TVM_GETNEXTITEM, TVGN_CHILD, hCurrentItem
.WHILE eax != NULL
mov hCurrentItem, eax
; check if correct item
Invoke TreeViewFindTextCheckString, hTreeview, hCurrentItem, lpszFindText
.IF eax == TRUE
mov eax, hCurrentItem
mov hFoundItem, eax
.BREAK
.ELSE
mov hFoundItem, 0
Invoke TreeViewFindItemBranch, hTreeview, hCurrentItem, lpszFindText
mov hFoundItem, eax
.ENDIF
.IF hFoundItem != 0
.BREAK
.ENDIF
Invoke SendMessage, hTreeview, TVM_GETNEXTITEM, TVGN_NEXT, hCurrentItem
.ENDW
mov eax, hFoundItem
ret
TreeViewFindItemBranch ENDP
;**************************************************************************
; TreeViewFindTextCheckString - check text matches, return true or false
;**************************************************************************
TreeViewFindTextCheckString PROC hTreeview:DWORD, hItem:DWORD, lpszFindText:DWORD
Invoke TreeViewGetItemText, hTreeview, hItem, Addr szTreeViewFindItemText, MAX_PATH
.IF eax != 0
Invoke szLen, Addr szTreeViewFindItemText
.IF eax == 0
mov eax, FALSE
ret
.ENDIF
Invoke TreeViewFindItemInString, 1, Addr szTreeViewFindItemText, lpszFindText
.IF sdword ptr eax > 0 ;eax == 0 ; no found sdword ptr eax > 0
mov eax, TRUE
.ELSE
mov eax, FALSE
.ENDIF
.ELSE
mov eax, FALSE
.ENDIF
ret
TreeViewFindTextCheckString ENDP
;**************************************************************************
; InString function taken from masm32 library
;**************************************************************************
TreeViewFindItemInString PROC USES EBX ECX EDX EDI ESI startpos:DWORD, lpSource:DWORD, lpPattern:DWORD
; ------------------------------------------------------------------
; InString searches for a substring in a larger string and if it is
; found, it returns its position in eax.
;
; It uses a one (1) based character index (1st character is 1,
; 2nd is 2 etc...) for both the "StartPos" parameter and the returned
; character position.
;
; Return Values.
; If the function succeeds, it returns the 1 based index of the start
; of the substring.
; 0 = no match found
; -1 = substring same length or longer than main string
; -2 = "StartPos" parameter out of range (less than 1 or longer than
; main string)
; ------------------------------------------------------------------
LOCAL sLen:DWORD
LOCAL pLen:DWORD
;push ebx
;push esi
;push edi
invoke lstrlen, lpSource
mov sLen, eax ; source length
invoke lstrlen, lpPattern
mov pLen, eax ; pattern length
cmp startpos, 1
jge @F
mov eax, -2
jmp isOut ; exit if startpos not 1 or greater
@@:
dec startpos ; correct from 1 to 0 based index
cmp eax, sLen
jl @F
mov eax, -1
jmp isOut ; exit if pattern longer than source
@@:
sub sLen, eax ; don't read past string end
inc sLen
mov ecx, sLen
cmp ecx, startpos
jg @F
mov eax, -2
jmp isOut ; exit if startpos is past end
@@:
; ----------------
; setup loop code
; ----------------
mov esi, lpSource
mov edi, lpPattern
mov al, [edi] ; get 1st char in pattern
add esi, ecx ; add source length
neg ecx ; invert sign
add ecx, startpos ; add starting offset
jmp Scan_Loop
align 16
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Pre_Scan:
inc ecx ; start on next byte
Scan_Loop:
cmp al, [esi+ecx] ; scan for 1st byte of pattern
je Pre_Match ; test if it matches
inc ecx
js Scan_Loop ; exit on sign inversion
jmp No_Match
Pre_Match:
lea ebx, [esi+ecx] ; put current scan address in EBX
mov edx, pLen ; put pattern length into EDX
Test_Match:
mov ah, [ebx+edx-1] ; load last byte of pattern length in main string
cmp ah, [edi+edx-1] ; compare it with last byte in pattern
jne Pre_Scan ; jump back on mismatch
dec edx
jnz Test_Match ; 0 = match, fall through on match
; @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Match:
add ecx, sLen
mov eax, ecx
inc eax
jmp isOut
No_Match:
xor eax, eax
isOut:
;pop edi
;pop esi
;pop ebx
ret
TreeViewFindItemInString ENDP