📄 objexp.bat
字号:
dec ebx ; make it zero based
mov [esi].iItem, ebx
ListView_GetItem g_hwndListView, esi
.if eax == TRUE
.if [esi].lParam != NULL
invoke free, [esi].lParam
.endif
.endif
.endw
assume esi:nothing
ListView_DeleteAllItems g_hwndListView
.endif
ret
DeleteListView endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; FillListView
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
FillListView proc uses esi edi ebx
local hSelectedTreeItem:HTREEITEM
local tvi:TV_ITEM
local lvi:LV_ITEMW
local puszSelectedDirectoryPath:LPWSTR
; invoke DeleteListView
ListView_DeleteAllItems g_hwndListView
; Remove up/down arrow image from list view header
invoke ImageToHeaderItem, g_hwndHeader, g_uPrevClickedColumn, NULL
or g_uPrevClickedColumn, -1
mov g_uSortOrder, SORT_NOT_YET
; Get selected tree view node
TreeView_GetSelection g_hwndTreeView
.if eax == 0
TreeView_GetRoot g_hwndTreeView
push eax
TreeView_SelectItem g_hwndTreeView, eax
pop eax
.endif
lea edi, tvi
assume edi:ptr TV_ITEM
mov [edi]._mask, TVIF_PARAM
mov [edi].hItem, eax
; Each tree view item contains associated string with directory path in lParam
TreeView_GetItem g_hwndTreeView, edi
m2m puszSelectedDirectoryPath, [edi].lParam
assume edi:nothing
.if eax == TRUE
invoke QueryDirectoryObject, puszSelectedDirectoryPath
.if eax != NULL
mov esi, eax ; -> array of DIRECTORY_BASIC_INFORMATION
push esi ; for call free
assume esi:ptr DIRECTORY_BASIC_INFORMATION
lea edi, lvi
assume edi:ptr LV_ITEMW
or [edi].iItem, -1
; Fill ListView
; The array is terminated with zeroed DIRECTORY_BASIC_INFORMATION structure
; But we check only first two dwords. It's enough.
.while (dword ptr [esi] != 0) && (dword ptr [esi][4] != 0)
mov [edi]._mask, LVIF_TEXT + LVIF_IMAGE + LVIF_PARAM
inc [edi].iItem ; next list view item
xor ebx, ebx ; undex
.while TRUE
; invoke wcscmp, [esi].ObjectTypeName.Buffer, g_apuszObjectTypeNames[ebx]
invoke _wcsicmp, [esi].ObjectTypeName.Buffer, g_apuszObjectTypeNames[ebx]
.if eax == 0
shr ebx, 2 ; / sizeof LPWSTR = image index
mov [edi].iImage, ebx
.break
.endif
add ebx, sizeof LPWSTR ; next type name
.break .if ebx > g_cbObjectTypeNames ; break if end of array
.endw
and [edi].iSubItem, 0
mrm [edi].pszText, [esi].ObjectName.Buffer
; Make full path to object and associate it with list view item
; Later we have manually free this memory
invoke MakeFullPath, puszSelectedDirectoryPath, addr [esi].ObjectName
mov [edi].lParam, eax ; pointer to unicode string with full path or NULL
invoke SendMessage, g_hwndListView, LVM_INSERTITEMW, 0, edi
and [edi]._mask, not (LVIF_PARAM + LVIF_IMAGE)
inc [edi].iSubItem
mrm [edi].pszText, [esi].ObjectTypeName.Buffer
invoke SendMessage, g_hwndListView, LVM_SETITEMW, 0, edi
invoke wcscmp, [esi].ObjectTypeName.Buffer, g_apuszObjectTypeNames[IMG_ID_SYMBOLIC_LINK * sizeof LPWSTR];$CTW0("SymbolicLink")
.if eax == 0
mov eax, [edi].lParam
.if eax != NULL
invoke QuerySymbolicLinkObject, eax
.if eax != NULL
push eax ; for free
inc [edi].iSubItem
mrm [edi].pszText, (UNICODE_STRING PTR [eax]).Buffer
invoke SendMessage, g_hwndListView, LVM_SETITEMW, 0, edi
call free
.endif
.endif
.endif
add esi, sizeof DIRECTORY_BASIC_INFORMATION
.endw
assume edi:nothing
assume esi:nothing
call free ; pointer to memory is on stack
.endif
.else
Fix
invoke ErrorToStatusBar, NULL
.endif
ret
FillListView endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; FreeTreeViewParam
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
FreeTreeViewParam proc uses esi ebx hTvItem:HTREEITEM
; recursively frees memory associated with each tree view item
local tvi:TV_ITEM
Fix Check this proc out
mov ebx, hTvItem
.if ebx != NULL ; tree view may be not yet created
lea esi, tvi
assume esi:ptr TV_ITEM
mov [esi]._mask, TVIF_PARAM
mov [esi].hItem, ebx
; Each tree view item contains associated string with directory path in lParam
TreeView_GetItem g_hwndTreeView, esi
.if eax == TRUE
.if [esi].lParam != NULL
invoke free, [esi].lParam
; and [esi].lParam, NULL
; TreeView_SetItem g_hwndTreeView, esi
.endif
.endif
assume esi:nothing
TreeView_GetChild g_hwndTreeView, ebx
.if eax != NULL
mov ebx, eax
invoke FreeTreeViewParam, ebx
.while TRUE
TreeView_GetNextSibling g_hwndTreeView, ebx
.break .if eax == NULL
mov ebx, eax
invoke FreeTreeViewParam, ebx
.endw
.endif
.endif
ret
FreeTreeViewParam endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; DeleteTreeView
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DeleteTreeView proc
; Frees all memory associated with each tree view item and deletes all items
TreeView_GetRoot g_hwndTreeView
.if eax != NULL ; tree view may be not yet created
invoke FreeTreeViewParam, eax
.endif
TreeView_DeleteAllItems g_hwndTreeView
ret
DeleteTreeView endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; Refresh
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Refresh proc uses esi ebx
local tvins:TV_INSERTSTRUCTW
local hRoot:HTREEITEM
Fix Damn. windows.inc has no usable support of UNICODE. Try to fix this later.
invoke DeleteTreeView
; Create TreeView Root
lea esi, tvins
assume esi:ptr TV_INSERTSTRUCTW
mov [esi].hParent, NULL
mov [esi].hInsertAfter, TVI_ROOT
mov [esi].item._mask, TVIF_TEXT + TVIF_SELECTEDIMAGE + TVIF_IMAGE + TVIF_PARAM
mov [esi].item.pszText, offset g_uszBackSlash
mov [esi].item.iImage, IMG_ID_DIRECTORY
mov [esi].item.iSelectedImage, IMG_ID_DIRECTORY_OPN
invoke malloc, sizeof g_uszBackSlash + sizeof WCHAR
mov ebx, eax
.if eax != NULL
invoke wcscpy, ebx, offset g_uszBackSlash
.endif
mov [esi].item.lParam, ebx
assume esi:nothing
;TreeView_InsertItem g_hwndTreeView, edi
invoke SendMessage, g_hwndTreeView, TVM_INSERTITEMW, 0, esi
mov hRoot, eax
; Start traveling through the Object Directory
invoke FillTreeViewNode, hRoot, offset g_uszBackSlash
TreeView_Expand g_hwndTreeView, hRoot, TVE_EXPAND
; TreeView_Select g_hwndTreeView, hRoot, TVGN_CARET + TVGN_FIRSTVISIBLE
TreeView_SelectItem g_hwndTreeView, hRoot
; invoke FillListView
ret
Refresh endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; CompareFunc
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CompareFunc proc uses esi lParam1:DWORD, lParam2:DWORD, uClickedColumn:UINT
; Case insensitive sort
local buffer[256]:CHAR
local buffer1[256]:CHAR
local lvi:LV_ITEM
lea esi, lvi
assume esi:ptr LV_ITEM
mov [esi].imask, LVIF_TEXT
lea eax,buffer
mov [esi].pszText, eax
mov [esi].cchTextMax, sizeof buffer
m2m [esi].iSubItem, uClickedColumn
assume esi:nothing
invoke SendMessage, g_hwndListView, LVM_GETITEMTEXT, lParam1, esi
invoke lstrcpy, addr buffer1, addr buffer
invoke SendMessage, g_hwndListView, LVM_GETITEMTEXT, lParam2, esi
.if g_uSortOrder == SORT_ASCENDING
invoke lstrcmpi, addr buffer1, addr buffer
.else
invoke lstrcmpi, addr buffer, addr buffer1
.endif
ret
CompareFunc endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; ListViewInsertColumn
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ListViewInsertColumn proc uses esi
local lvc:LV_COLUMN
lea esi, lvc
assume esi:ptr LV_COLUMN
mov [esi].imask, LVCF_TEXT + LVCF_WIDTH
mov [esi].pszText, $CTA0("Object Name")
mov [esi].lx, 280
ListView_InsertColumn g_hwndListView, LVCOL_NAME, esi
mov [esi].pszText, $CTA0("Object Type Name")
mov [esi].lx, 108
ListView_InsertColumn g_hwndListView, LVCOL_TYPE, esi
mov [esi].pszText, $CTA0("Symbolic Link")
mov [esi].lx, 180
ListView_InsertColumn g_hwndListView, LVCOL_LINK, esi
assume esi:nothing
ret
ListViewInsertColumn endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DrawXorBar proc hdc:HDC, x1:UINT, y1:UINT, uWidth:UINT, uHeight:UINT
local hbm:HBITMAP
local hbr:HBRUSH
local hbrushOld:HBRUSH
.data
align DWORD
dotPattern dw 0AAAAh, 5555h, 0AAAAh, 5555h, 0AAAAh, 5555h, 0AAAAh, 5555h
.code
mov hbm, $invoke(CreateBitmap, 8, 8, 1, 1, addr dotPattern)
mov hbr, $invoke(CreatePatternBrush, hbm)
; mov eax, y1
; add eax, g_cyXorBarIndentTop
invoke SetBrushOrgEx, hdc, x1, y1, NULL
mov hbrushOld, $invoke(SelectObject, hdc, hbr)
mov eax, y1
add eax, g_cyXorBarIndentTop
mov ecx, uHeight
sub ecx, g_cyXorBarIndentTop
sub ecx, g_cyXorBarIndentBot
invoke PatBlt, hdc, x1, eax, uWidth, ecx, PATINVERT
invoke SelectObject, hdc, hbrushOld
invoke DeleteObject, hbr
invoke DeleteObject, hbm
ret
DrawXorBar endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Splitter_OnLButtonDown proc hWnd:HWND, iMsg:UINT, wParam:WPARAM, lParam:LPARAM
local pt:POINT
local hdc:HDC
local rect:RECT
mov pt.x, $LOWORD(lParam) ; horizontal position of cursor
mov pt.y, $HIWORD(lParam)
invoke GetWindowRect, hWnd, addr rect
; convert the mouse coordinates relative to the top-left of the window
invoke ClientToScreen, hWnd, addr pt
mov eax, rect.left
sub pt.x, eax ; pt.x -= rect.left
mov eax, rect.top
sub pt.y, eax ; pt.y -= rect.top
; same for the window coordinates - make them relative to 0,0
not rect.left
inc rect.left ; -rect.left
not rect.top
inc rect.top ; -rect.top
invoke OffsetRect, addr rect, rect.left, rect.top
.if pt.x < cxSplitterIndentL
mov pt.x, cxSplitterIndentL
.endif
;
mov eax, rect.right
sub eax, cxSplitterIndentR
.if pt.x > eax
mov pt.x, eax
.endif
mov g_fDragMode, TRUE
invoke SetCapture, hWnd
mov hdc, $invoke(GetWindowDC, hWnd)
mov ecx, pt.x
sub ecx, 2
mov eax, rect.bottom
sub eax, 8
invoke DrawXorBar, hdc, ecx, 4, 4, eax
invoke ReleaseDC, hWnd, hdc
m2m g_oldy, pt.x
xor eax, eax
ret
Splitter_OnLButtonDown endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Splitter_OnLButtonUp proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
local pt:POINT
local hdc:HDC
local rect:RECT
.if g_fDragMode != FALSE
mov pt.x, $LOWORD(lParam) ; horizontal position of cursor
mov pt.y, $HIWORD(lParam)
invoke GetWindowRect, hWnd, addr rect
; convert the mouse coordinates relative to the top-left of the window
invoke ClientToScreen, hWnd, addr pt
mov eax, rect.left
sub pt.x, eax ; pt.x -= rect.left
mov eax, rect.top
sub pt.y, eax ; pt.y -= rect.top
; same for the window coordinates - make them relative to 0,0
not rect.left
inc rect.left ; -rect.left
not rect.top
inc rect.top ; -rect.top
invoke OffsetRect, addr rect, rect.left, rect.top
mov eax, pt.x
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -