📄 mrufiles.asm
字号:
title MRUFiles
.586
.model flat, STDCALL
option casemap: none ; Case sensitive
include L:\AsmEdit\include\Windows.inc
include user32.inc
include kernel32.inc
include advapi32.inc
include L:\AsmEdit\include\DSPMACRO.asm
MOVmd MACRO Var1, Var2
push Var2
pop Var1
ENDM
; include AsmEdit.inc
;--------------------------------------------------
.data
szREGSZ db 'REG_SZ',0
szRecentKey db '\Recent File List',0
szWorkKey db '\Work',0
szRecent db 100 dup(?),0
szRegWork db 100 dup(?),0
szName db 'File '
szIndex db 2 dup(?),0
szBackS db '\',0
szFill db '...',0
fmat2 db '%02u',0
;--------------------------------------------------
.code
;=========================================================================|
;* Process the MRU file list procedure |
;=========================================================================|
ProcessMRUFiles proc hwnd:DWORD, Init:DWORD, MenuItems:DWORD, szPath, szRegName, hmenu
LOCAL hSMenu:DWORD, MenuCnt:DWORD, MenuID:DWORD, ItemCnt:DWORD, Recent:DWORD
LOCAL lpcbValueName:DWORD, lpcValues:DWORD, lpdwDisp:DWORD, lpcbData:DWORD
LOCAL hKey:DWORD, hKeyW:DWORD, hKeyE:DWORD, hKeyS:DWORD, Cnt:DWORD
LOCAL szData[150]:BYTE, szWork[150]:BYTE
INVOKE lstrcpy, addr szRecent, szRegName
INVOKE lstrcat, addr szRecent, addr szRecentKey
INVOKE lstrcpy, addr szRegWork, szRegName
INVOKE lstrcat, addr szRegWork, addr szWorkKey
mov Recent, 0
.if !hmenu
INVOKE GetMenu, hwnd ; Get handle to main menu
INVOKE GetSubMenu, eax, 0 ; Get handle to 1st sub menu
.else
mov eax, hmenu
.endif
mov hSMenu, eax
INVOKE GetMenuItemCount, hSMenu ; Get count of items in the sub menu
.if hmenu
inc eax
.endif
mov MenuCnt, eax
;--------------- [Delete the menu file names] ---------------
mov eax, MenuItems
.if MenuCnt > eax
sub MenuCnt, eax
mov Cnt, 1401
.while MenuCnt
INVOKE DeleteMenu, hSMenu, Cnt, MF_BYCOMMAND
sub MenuCnt, 1
add Cnt, 1
.endw
.endif
;--------------- [Open or create the recent and work registry] ---------------
INVOKE RegCreateKeyEx, HKEY_CURRENT_USER, offset szRecent, 0, offset szREGSZ, 0,\
KEY_WRITE or KEY_READ, 0, addr hKey, addr lpdwDisp
INVOKE RegCreateKeyEx, HKEY_CURRENT_USER, offset szRegWork, 0, offset szREGSZ, 0,\
KEY_WRITE or KEY_READ, 0, addr hKeyW, addr lpdwDisp
.if Init ; Program startup
mov ItemCnt, 0
jmp InitLoad
.endif
mov ItemCnt, 1
INVOKE wsprintf, addr szIndex, addr fmat2, ItemCnt
;--------------- [Write the new path to the work registry] ---------------
INVOKE lstrlen, szPath
mov lpcbData, eax
INVOKE RegSetValueEx, hKeyW, addr szName, 0, REG_SZ, szPath, lpcbData
InitLoad:
;--------------- [Get the number of items in the recent registry] ---------------
INVOKE RegQueryInfoKey, hKey, 0, 0, 0, 0, 0, 0, addr lpcValues, 0, 0, 0, 0
.if Init && !lpcValues ; Program startup
jmp GetOut
.endif
MOVmd hKeyE, hKey
MOVmd hKeyS, hKeyW
MOVmd MenuCnt, MenuItems
sub MenuCnt, 2
mov MenuID, 1400
LoopReg:
;--------------- [Enumerate either the recent or work registry] ---------------
mov Cnt, 0
.if lpcValues > 15
mov lpcValues, 15 ; Set file list limit
.endif
.while lpcValues
sub lpcValues, 1
mov lpcbValueName, 8
mov lpcbData, 150
INVOKE RegEnumValue, hKeyE, Cnt, addr szName, addr lpcbValueName, 0, addr szREGSZ, addr szData, addr lpcbData
add Cnt, 1
;--------------- [Check for dupes or delete if writting to the work registry] ---------------
.if !Recent
INVOKE lstrcmpi, addr szData, szPath
test eax, eax
jz Dupe
.endif
add ItemCnt, 1
INVOKE wsprintf, addr szIndex, addr fmat2, ItemCnt
INVOKE lstrlen, addr szData
mov lpcbData, eax
INVOKE RegSetValueEx, hKeyS, addr szName, 0, REG_SZ, addr szData, lpcbData
;--------------- [If on the last copy, fill the sub menu with the list file names] ---------------
.if Recent
add MenuCnt, 1
add MenuID, 1
.if lpcbData > 35
INVOKE lstrcpy, addr szWork, addr szData
INVOKE lstrcpyn, addr szWork, addr szWork, 4
INVOKE lstrcat, addr szWork, addr szFill
lea eax, szData
add eax, lpcbData
sub eax, 28
INVOKE lstrcat, addr szWork, eax
INVOKE lstrcpy, addr szData, addr szWork
.endif
INVOKE InsertMenu, hSMenu, MenuCnt, MF_BYPOSITION or MF_STRING, MenuID, addr szData
.endif
Dupe:
.endw
.if Recent
jmp DelWork
.endif
;--------------- [Delete and reset the recent registry] ---------------
INVOKE RegDeleteKey, HKEY_CURRENT_USER, offset szRecent
INVOKE RegCloseKey, hKey
INVOKE RegCreateKeyEx, HKEY_CURRENT_USER, offset szRecent, 0, offset szREGSZ, 0,\
KEY_WRITE or KEY_READ, 0, addr hKey, addr lpdwDisp
and ItemCnt, 0
;--------------- [Toggle the keys] ---------------
MOVmd hKeyE, hKeyW
MOVmd hKeyS, hKey
;--------------- [Get the number of items in the work registry] ---------------
INVOKE RegQueryInfoKey, hKeyW, 0, 0, 0, 0, 0, 0, addr lpcValues, 0, 0, 0, 0
or Recent, 1
jmp LoopReg
DelWork:
;--------------- [Delete the work registry] ---------------
INVOKE RegDeleteKey, HKEY_CURRENT_USER, offset szRegWork
;--------------- [Add a separator to the end of the file list] ---------------
add MenuCnt, 1
add MenuID, 1
INVOKE InsertMenu, hSMenu, MenuCnt, MF_BYPOSITION or MF_SEPARATOR, MenuID, addr szData
GetOut:
INVOKE RegCloseKey, hKey
INVOKE RegCloseKey, hKeyW
ret
ProcessMRUFiles endp
;=========================================================================|
;* Get the registry path name from the menu drop down file list procedure |
;=========================================================================|
GetRegPath proc ID:DWORD, szRegName
LOCAL hKey:DWORD, lpcbData:DWORD, lpdwDisp:DWORD, ItemCnt:DWORD
LOCAL szData[150]:BYTE
INVOKE lstrcpy, addr szRecent, szRegName
INVOKE lstrcat, addr szRecent, addr szRecentKey
MOVmd ItemCnt, ID
sub ItemCnt, 1400
INVOKE wsprintf, addr szIndex, addr fmat2, ItemCnt
INVOKE RegOpenKeyEx, HKEY_CURRENT_USER, offset szRecent, 0, KEY_QUERY_VALUE, addr hKey
mov lpcbData, 150
INVOKE RegQueryValueEx, hKey, addr szName, 0, addr szREGSZ, addr szData, addr lpcbData
INVOKE RegCloseKey, hKey
lea eax, szData
ret
GetRegPath endp
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -