3月份写的代码,今天一看。晕。思路都忘光了。看来有必要把注释加上啊。还好当初加了些上去。(希望能同道合者交流)
功能:
1.锁定屏幕,禁止其他人操作。
2.添加了显示图片透明度,方便游戏者挂机(设置透明度为0即显示全部屏幕,但无法对计算机进行操作)
3.添加了播放MP3的功能,这样方便挂机后不用打开其他播放器即可听音乐。
(待修改的地方:图片不可变,有时间添加一个可载入图片功能,这样就可以让用户自己设置挂机图片了。禁止使用Ctrl+Alt+Del功能使用的是修改注册表,懒。。有时间研究一下其它方法)
程序下载:
http://m.99081.com/a33445621/挂机锁.rar
.386
.model flat, stdcall
option casemap :none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
include comdlg32.inc
includelib comdlg32.lib
include gdi32.inc
includelib gdi32.lib
include debug.inc ;因为使用了CTEXT宏,所以要加入debug.inc和debug.lib
includelib debug.lib
include winmm.inc ;使用了音乐播放函数
includelib winmm.lib
include advapi32.inc ;使用了注册表函数
includelib advapi32.lib
KBDLLHOOKSTRUCT struct ;低层键盘钩子要用到的数据结构,RadASM没包含,只能自己定义
vkCode DWORD ? ;LowLevelKeyboardProc过程中_lParam是这个数据结构
scanCode DWORD ?
flags DWORD ?
time DWORD ?
dwExtraInfo DWORD ?
KBDLLHOOKSTRUCT ends
IDB_BMP equ 1000
DLG_MAIN equ 1000
DLG_SHOW equ 1002
ICO_MAIN equ 1001
IDC1_SHOWTEXT equ 1001
IDC1_PASS equ 1003
IDC1_REPASS equ 1002
IDC1_OK equ 1004
IDC1_EXIT equ 1005
IDC2_OK equ 1006
IDC2_PASS equ 1007
IDC1_ICO equ 1008
IDC1_PROMPT equ 1009
IDC1_SCROLL equ 1010
IDC1_COUNT equ 1011
IDC1_ABOUT equ 1012
IDC1_FILE equ 1006
IDC1_BROWSE equ 1008
IDC1_PLAY equ 1013
.data?
hInstance dd ? ;主窗口的句柄
hWinDlg1 dd ? ;主窗口的句柄
hInstance1 dd ? ;锁屏窗口的句柄
hWinMain dd ? ;锁屏窗口的句柄
hBitMap dd ? ;锁屏窗口背景图标的句柄
hIcon dd ? ;图标
hHook dd ? ;钩子句柄
dwFlag dd ? ;密码是否相等的标志,0为密码不匹配,1为匹配,2无意
szPassWordBuf db 128 dup (?) ;主窗口第一个密码框的Buffer,即IDC1_PASS的Buffer
dwLength dd ? ;用来存入输入的密码长度
szShowText db 128 dup (?) ;屏幕显示内容的Buffer
dwPos dd ? ;滚动条的位置
szFileName db MAX_PATH dup (?)
hDevice dd ?
dwFlag2 dd ?
.const
szClassName db 'Class',0 ;类的名字
szPassWordFmt db '请记住您的密码:%s',0
szTaskBar db 'Shell_traywnd',0 ;获取任务栏句柄的时候要用到字符串
szAbout db ' By:未秋叶已落 ',0dh,0ah,' QQ:307727654 ',0dh,0ah,' 渭南*师
院',0dh,0ah,' 2009.3.21',0
szSubKey db 'Software/Microsoft/windows/CurrentVersion/Policies/System',0
szValueName db 'DisableTaskMgr',0
szValue db '1',0 ;用来锁定注册表
szFilter db 'Mp3 File(*.mp3)',0,'*.mp3',0,0
szDevice db "MPEGVideo",0
.code
LowLevelKeyboardProc proc _dwCode,_wParam,_lParam ;钩子的过程
invoke CallNextHookEx,hHook,_dwCode,_wParam,_lParam
.if _dwCode == HC_ACTION
mov ebx,_lParam
assume ebx:ptr KBDLLHOOKSTRUCT ;屏蔽掉一些系统键
.if [ebx].vkCode == VK_DELETE || [ebx].vkCode == VK_LWIN ||/
[ebx].vkCode == VK_TAB || [ebx].vkCode == VK_SHIFT ||/
[ebx].vkCode == VK_MENU || [ebx].vkCode == VK_ESCAPE||/
[ebx].vkCode == VK_RWIN || [ebx].vkCode == VK_CONTROL
invoke FindWindow,addr szTaskBar,0 ;获取任务栏句柄
invoke EnableWindow,eax,FALSE ;设置任务栏为不可用
mov eax,1
.endif
.endif
ret
LowLevelKeyboardProc endp
_CmpPassWord proc _lpPassWord1,_lpPassWord2,_dwPassWordlength ;比对两个密码是否一样
pushad
mov dwFlag,2
mov esi,_lpPassWord1
mov edi,_lpPassWord2
mov ecx,_dwPassWordlength
xor edx,edx
cld
@@:
lodsb
cmp al,[edi+edx]
jnz @F
dec ecx
inc edx
test ecx,ecx
jnz @B
mov dwFlag,1
ret
@@:
mov dwFlag,0
popad
ret
_CmpPassWord endp
_ProcDlgMain1 proc uses ebx edi esi hWnd,uMsg,wParam,lParam ;进入的主窗口
LOCAL @szRePassWord[128]:byte ;第二个密码框的Buffer
LOCAL @szBuffer[128]:byte ;用来显示密码的Buffer
mov eax,uMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
invoke ExitProcess,NULL
.elseif eax == WM_INITDIALOG
push hWnd
pop hWinDlg1
invoke LoadIcon,hInstance,ICO_MAIN ;装载图标文件
mov hIcon,eax
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,eax ;设置图标
invoke SetDlgItemText,hWnd,IDC1_SHOWTEXT,/
CTEXT("请误操作此电脑!谢谢合作!") ;设置屏幕显示内容的初始值
invoke CheckDlgButton,hWnd,IDC1_PROMPT,BST_CHECKED;初始化显示密码为已选状态
invoke SendDlgItemMessage,hWnd,IDC1_SCROLL,SBM_SETRANGE,0,255;初始化滚动条0-255
invoke SendDlgItemMessage,hWnd,IDC1_SCROLL,SBM_SETPOS,100,TRUE;初始化滚动条位置
为100
invoke SetDlgItemInt,hWnd,IDC1_COUNT,100,FALSE;初始化滚动条记数为100
mov dwPos,100 ;初始化滚动条位置的变量为100
.elseif eax == WM_COMMAND
.if wParam == IDC1_OK
invoke GetDlgItemText,hWnd,IDC1_SHOWTEXT,addr szShowText,/
sizeof szShowText ;获取屏幕显示的文字
invoke GetDlgItemText,hWnd,IDC1_PASS,addr szPassWordBuf,/
sizeof szPassWordBuf ;获取第一个密码框密码
mov dwLength,eax
invoke GetDlgItemText,hWnd,IDC1_REPASS,addr @szRePassWord,/
sizeof @szRePassWord ;获取第二个密码框密码
.if eax != dwLength ;判断两次密码的长度是否一志
invoke MessageBox,hWnd,CTEXT("两次输入密码不一样"),/
CTEXT("错误"),MB_OK or MB_ICONWARNING
ret
.elseif eax == 0
invoke MessageBox,hWnd,CTEXT("密码不能为空"),/
CTEXT("错误"),MB_OK or MB_ICONEXCLAMATION
ret
.endif
invoke _CmpPassWord,addr szPassWordBuf,/
addr @szRePassWord,dwLength;比较密码是否一志
.if dwFlag == 0
invoke MessageBox,hWnd,CTEXT("两次输入密码不一样"),/
CTEXT("错误"),MB_OK or MB_ICONWARNING
.elseif dwFlag == 1
invoke IsDlgButtonChecked,hWnd,IDC1_PROMPT;检查显示密码选项
.if eax == BST_CHECKED
invoke wsprintf,addr @szBuffer,addr szPassWordFmt,/
addr szPassWordBuf ;用来显示密码
invoke MessageBox,hWnd,addr @szBuffer,CTEXT("提示"),/
MB_OK or MB_ICONEXCLAMATION
.endif
invoke EndDialog,hWnd,NULL ;关闭对话框
call _WinMain ;显示挂机窗口
.endif
ret
.elseif wParam == IDC1_EXIT
invoke EndDialog,hWnd,NULL
invoke ExitProcess,NULL
.elseif wParam == IDC1_ABOUT
invoke MessageBox,hWnd,offset szAbout,CTEXT("挂机锁v1.0"),MB_OK
.elseif wParam == IDC1_BROWSE
call _GetFile
.elseif wParam == IDC1_PLAY
.if dwFlag2 == 0
call _PlayMP3
.else
call _StopPlayMP3
.endif
.endif
.elseif eax == WM_HSCROLL ;wParam的高16位是滚动条当前位置
mov eax,wParam ;wParam的低16位是滚动条动作码
.if ax == SB_LINELEFT
dec dwPos
.elseif ax == SB_LINERIGHT
inc dwPos
.elseif ax == SB_PAGELEFT
sub dwPos,10
.elseif ax == SB_PAGERIGHT
add dwPos,10
.elseif ax == SB_THUMBPOSITION || ax == SB_THUMBTRACK
mov eax,wParam
shr eax,16 ;wParam的高16位是滚动条当前位置
mov dwPos,eax
.else
mov eax,TRUE
ret
.endif
cmp dwPos,0
jge @F
mov dwPos,0
@@:
cmp dwPos,255
jle @F
mov dwPos,255
@@:
invoke SetDlgItemInt,hWnd,IDC1_COUNT,dwPos,FALSE
invoke SendDlgItemMessage,hWnd,IDC1_SCROLL,SBM_SETPOS,dwPos,TRUE
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain1 endp
_ProcDlgMain2 proc uses ebx edi esi hWnd,uMsg,wParam,lParam ;输入密码窗口
LOCAL @szPassWord[128]:byte ;输入密码的Buffer
LOCAL @stRect:RECT
LOCAL @hKey
mov eax,uMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
invoke GetWindowRect,hWnd,addr @stRect ;获取窗口的尺寸
invoke ClipCursor,addr @stRect ;限制鼠标移动范围
invoke SendMessage,hWnd,WM_SETICON,ICON_BIG,hIcon ;设置对话框图标
.elseif eax == WM_COMMAND
.if wParam == IDC2_OK
invoke GetDlgItemText,hWnd,IDC2_PASS,addr @szPassWord,/
sizeof @szPassWord
.if eax == 0
invoke MessageBox,hWnd,CTEXT("密码不能为空!"),/
CTEXT("错误"),MB_OK or MB_ICONWARNING
ret
.elseif eax != dwLength ;判断密码的长度是否一志
invoke MessageBox,hWnd,CTEXT("输入密码不正确!"),/
CTEXT("错误"),MB_OK or MB_ICONEXCLAMATION
ret
.endif
invoke _CmpPassWord,addr szPassWordBuf,addr @szPassWord,eax
.if dwFlag == 0
invoke MessageBox,hWnd,CTEXT("输入密码不正确!"),/
CTEXT("错误"),MB_OK or MB_ICONWARNING
.elseif dwFlag == 1
invoke FindWindow,addr szTaskBar,0 ;获取任务栏句柄
invoke EnableWindow,eax,TRUE ;设置任务栏为可用
invoke UnhookWindowsHookEx,hHook ;卸载钩子
; invoke ExitProcess,NULL ;退出程序
invoke ShowWindow,hWinDlg1,SW_SHOWNORMAL
invoke DestroyWindow,hWinMain
invoke EndDialog,hWnd,NULL
invoke GetWindowRect,hWnd,addr @stRect
invoke ClipCursor,addr @stRect
invoke RegOpenKeyEx,HKEY_CURRENT_USER,addr szSubKey,/
0,KEY_ALL_ACCESS,addr @hKey
invoke RegDeleteValue,@hKey,addr szValueName
invoke RegCloseKey,@hKey ;用来解锁注册表
.endif
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
_ProcDlgMain2 endp
_WinMain proc ;锁屏窗口
LOCAL @stWndClass:WNDCLASSEX
LOCAL @stMsg:MSG
invoke GetModuleHandle,NULL
mov hInstance1,eax
invoke RtlZeroMemory,addr @stWndClass,sizeof @stWndClass
push hInstance1
pop @stWndClass.hInstance
mov @stWndClass.cbSize,sizeof WNDCLASSEX
mov @stWndClass.lpfnWndProc,offset _ProcWinMain
mov @stWndClass.lpszClassName,offset szClassName
mov @stWndClass.style,CS_DBLCLKS
invoke LoadCursor,hWinMain,IDC_ARROW
mov @stWndClass.hCursor,eax
invoke RegisterClassEx,addr @stWndClass
invoke CreateWindowEx,WS_EX_TOPMOST,offset
szClassName,0,WS_POPUPWINDOW,0,0,0,0,0,0,hInstance,0
mov hWinMain,eax
invoke ShowWindow,eax,SW_SHOWMAXIMIZED
invoke UpdateWindow,hWinMain
.while TRUE
invoke GetMessage,addr @stMsg,NULL,0,0
.break .if eax == 0
invoke TranslateMessage,addr @stMsg
invoke DispatchMessage,addr @stMsg
.endw
ret
_WinMain endp
_ProcWinMain proc uses ebx edi esi hWnd,uMsg,wParam,lParam ;锁屏窗口过程
LOCAL @stPs:PAINTSTRUCT
LOCAL @hDc,@hBmpDc
LOCAL @stRect:RECT
LOCAL @hKey,@dwSize
mov eax,uMsg
.if eax == WM_CLOSE
invoke DestroyWindow,hWinMain
invoke PostQuitMessage,NULL
.elseif eax == WM_CREATE
invoke LoadBitmap,hInstance1,IDB_BMP
mov hBitMap,eax
invoke GetWindowLong,hWnd,GWL_EXSTYLE ;设置窗口透明度dwPos.
or eax,WS_EX_LAYERED
invoke SetWindowLong,hWnd,GWL_EXSTYLE,eax
invoke SetLayeredWindowAttributes,hWnd,0,dwPos,LWA_ALPHA
invoke SetWindowsHookEx,WH_KEYBOARD_LL,LowLevelKeyboardProc,/
hInstance,NULL ;Hook键盘消息过程为LowLevelKeyboardProc
mov @dwSize,sizeof szValue
invoke RegCreateKeyEx,HKEY_CURRENT_USER,addr
szSubKey,0,NULL,NULL,KEY_ALL_ACCESS,NULL,addr @hKey,NULL
invoke RegSetValueEx,@hKey,addr szValueName,0,REG_SZ,addr szValue,@dwSize
invoke RegCloseKey,@hKey ;用来锁定注册表
.elseif eax == WM_PAINT ;显示背景图片
invoke BeginPaint,hWinMain,addr @stPs
mov @hDc,eax
invoke CreateCompatibleDC,@hDc
mov @hBmpDc,eax
invoke SelectObject,@hBmpDc,hBitMap
invoke GetClientRect,hWinMain,addr @stRect
invoke BitBlt,@hDc,0,0,@stRect.right,@stRect.bottom,@hBmpDc,0,0,SRCCOPY
invoke DrawText,@hDc,addr szShowText,-1,addr @stRect,DT_CENTER or /
DT_SINGLELINE or DT_VCENTER ;显示屏幕文字
invoke DeleteDC,@hBmpDc
invoke EndPaint,hWinMain,addr @stPs
.elseif eax == WM_LBUTTONDOWN
invoke DialogBoxParam,hInstance,DLG_MAIN,hWnd,offset _ProcDlgMain2,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
_ProcWinMain endp
_PlayMP3 proc
local @stMCIOpen:MCI_OPEN_PARMS
local @stMCIPlay:MCI_PLAY_PARMS
mov @stMCIOpen.lpstrDeviceType,offset szDevice
mov @stMCIOpen.lpstrElementName,offset szFileName
invoke mciSendCommand,0,MCI_OPEN,MCI_OPEN_TYPE or MCI_OPEN_ELEMENT,addr @stMCIOpen
mov eax,@stMCIOpen.wDeviceID
mov hDevice,eax
mov eax,hWinDlg1
mov @stMCIPlay.dwCallback,eax
invoke mciSendCommand,hDevice,MCI_PLAY,MCI_NOTIFY,addr @stMCIPlay
.if eax == 0
invoke SetDlgItemText,hWinDlg1,IDC1_PLAY,CTEXT("停止")
mov dwFlag2,1
.endif
ret
_PlayMP3 endp
_StopPlayMP3 proc
local @stMCIStop:MCI_GENERIC_PARMS
mov eax,hWinDlg1
mov @stMCIStop.dwCallback,eax
invoke mciSendCommand,hDevice,MCI_STOP,MCI_NOTIFY,addr @stMCIStop
invoke mciSendCommand,hDevice,MCI_CLOSE,MCI_NOTIFY,addr @stMCIStop
invoke SetDlgItemText,hWinDlg1,IDC1_PLAY,CTEXT("播放")
mov dwFlag2,0
ret
_StopPlayMP3 endp
_GetFile proc
LOCAL @stOF:OPENFILENAME
invoke RtlZeroMemory,addr @stOF,sizeof @stOF
mov @stOF.lStructSize,sizeof @stOF
push hWinDlg1
pop @stOF.hwndOwner
mov @stOF.lpstrFilter,offset szFilter
mov @stOF.lpstrFile,offset szFileName
mov @stOF.nMaxFile,MAX_PATH
mov @stOF.Flags,OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST
invoke GetOpenFileName,addr @stOF
.if eax
invoke SetDlgItemText,hWinDlg1,IDC1_FILE,addr szFileName
call _StopPlayMP3
.endif
ret
_GetFile endp
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_SHOW,NULL,offset _ProcDlgMain1,NULL
invoke ExitProcess,NULL
end start