![]() |
#2
zklhp2009-12-27 19:09
帖一下代码罢
![]() ;MASMPlus 代码模板 - 普通的 Windows 程序代码 ;***************************************************************************************************************** ;作者:zklhp ;Email:zklhp@最后更新:2009.12.27 ;版权所有 转载请保持完整 ;***************************************************************************************************************** .386 .Model Flat, StdCall Option Casemap :None Include windows.inc Include user32.inc Include kernel32.inc Include shell32.inc Include gdi32.inc Include user32.inc includelib gdi32.lib IncludeLib user32.lib IncludeLib kernel32.lib IncludeLib user32.lib IncludeLib shell32.lib include macro.asm include rsrc.inc WM_SHELLNOTIFY equ WM_USER+5 IDI_TRAY equ 0 IDM_ABOUT equ 1000 IDM_EXIT equ 1010 IDM_HELP equ 1020 IDM_SETTING equ 1030 ;0 - 0BFFFh WIN0 EQU 9 WIN1 EQU 0 WIN2 EQU 1 WIN3 EQU 2 WIN4 EQU 3 WIN5 EQU 4 WIN6 EQU 5 WIN7 EQU 6 WIN8 EQU 7 WIN9 EQU 8 NEWDESKTOP struct hDesktop dd ? fIsShell dd ? ;TRUE为已运行explorer NEWDESKTOP ends ;IE6及以上版本的 NOTIFYICONDATA 结构和常量 NOTIFYICONDATA_ struct cbSize DWORD ? hwnd DWORD ? uID DWORD ? uFlags DWORD ? uCallbackMessage DWORD ? hIcon DWORD ? szTip BYTE 128 dup (?) dwState DWORD ? dwStateMask DWORD ? szInfo BYTE 256 dup (?) union uTimeout DWORD ? uVersion DWORD ? ends szInfoTitle BYTE 64 dup (?) dwInfoFlags DWORD ? GuidItem GUID <?> NOTIFYICONDATA_ ends NIF_INFO equ 010h NIIF_INFO equ 01h WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD .data dwNewDesktopNum dd 1 ;新建桌面数 szClassName db 'MD_TrayIconWinClass',0 szAppName db 'Multi-Desktop v0.1',0 szSettingString db '&Setting',0 szAboutString db '&About',0 szHelpString db '&Help',0 szFmtDesktopNum db '现在共有%d个桌面',0 szAboutText db 'Multi-Desktop v0.1',0dh,0ah,'By zklhp',0dh,0ah,'Email:zklhp@',0dh,0ah db '版权所有 转载请保持完整 谢谢!',0 szHelpText db '程序默认建立一个桌面 可通过快捷键WIN+1访问 WIN+`(`是键盘1前面那个)为当前桌面',0dh,0ah db '桌面的个数可以通过设置改变 最大支持新建9个桌面',0dh,0ah,'切换到新建桌面的快捷键将按 WIN+1 WIN+2 WIN+3 依次递增',0dh,0ah db '不推荐频繁改变新建桌面数 为什么自己试试就知道了 也不推荐重复运行(就是关了再开)本程序',0 szExitString db 'E&xit Program',0 szInitInfo db 'Multi-Desktop已启动 现在您可以切换到其他桌面 默认建立一个桌面 可通过快捷键WIN+1访问 如果您不会使用请查看帮助~',0 .data? hMutex dd ? hInstance dd ? hWinMain dd ? hPopupMenu dd ? note NOTIFYICONDATA_ <> stDesktop NEWDESKTOP 8 dup(<>) hCurrentDesktop dd ? dwMsgTaskbarRestart dd ? szBuf db 64 dup(?) .CODE start: ;为防止有多个进程同时运行 使用互斥体判断 ;是否有运行标志 invoke CreateMutex,NULL,FALSE,CTXT('MD_RUNNING') mov hMutex,eax invoke GetLastError .if eax == ERROR_ALREADY_EXISTS ;有则退出 invoke ExitProcess,0 .endif invoke GetModuleHandle,NULL mov hInstance,eax invoke WinMain,hInstance,NULL,NULL,SW_HIDE invoke ExitProcess,eax _CreateDesktop proc uses edi esi _lpParam:DWORD xor edi,edi lea esi,stDesktop assume esi:ptr NEWDESKTOP .while edi < dwNewDesktopNum invoke wsprintf,offset szBuf,CTXT('MD_Desktop%d'),edi ;MD_Desktop0 到 MD_Desktop8 invoke OpenDesktop,offset szBuf,0,FALSE,0 ;看桌面是否已经存在 .if !eax invoke CloseDesktop,eax ;存在则先关闭 .endif invoke CreateDesktop,offset szBuf,NULL,NULL,0,GENERIC_ALL,NULL .if eax mov [esi].hDesktop,eax mov [esi].fIsShell,FALSE ;对重复运行无效 ;invoke SetThreadDesktop,eax ;这个不知道干什么用的 貌似注释了也可以用~ .endif add esi,sizeof NEWDESKTOP inc edi .endw assume esi:NOTHING ret _CreateDesktop endp WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD local @stWndClass:WNDCLASSEX local @stMsg:MSG invoke RtlZeroMemory, addr @stWndClass, sizeof @stWndClass invoke LoadCursor, 0, IDC_ARROW mov @stWndClass.hCursor, eax mov eax, hInstance mov @stWndClass.hInstance, eax mov @stWndClass.cbSize, sizeof WNDCLASSEX mov @stWndClass.lpfnWndProc, offset WndProc mov @stWndClass.hbrBackground, COLOR_WINDOW + 1 mov @stWndClass.lpszClassName, offset szClassName invoke RegisterClassEx, addr @stWndClass ;创建无标题栏的窗口 invoke CreateWindowEx, WS_EX_TOOLWINDOW, addr szClassName,NULL, WS_POPUP or WS_SYSMENU, 0, 0, 0, 0,NULL, NULL, hInstance, NULL mov hWinMain, eax invoke ShowWindow, hWinMain, SW_SHOWNORMAL 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 DlgProc proc hWnd,uMsg,wParam,lParam .if uMsg==WM_INITDIALOG invoke LoadIcon,hInstance,ICON_168 mov eax,dwNewDesktopNum invoke SetDlgItemInt,hWnd,IDC_EDT1,eax,FALSE .elseif uMsg==WM_COMMAND mov eax,wParam and eax,0ffffh .if eax==IDOK invoke SendMessage,hWnd,WM_COMMAND,IDC_BTN1,0 ;按回车是确定 .elseif eax==IDCANCEL invoke SendMessage,hWnd,WM_CLOSE,0,0 ;按ESC退出 .elseif eax==IDC_BTN1 ;确定 invoke GetDlgItemInt,hWnd,IDC_EDT1,FALSE,FALSE .if eax < 10 && eax >0 mov dwNewDesktopNum,eax invoke SendMessage,hWnd,WM_CLOSE,0,0 .endif .elseif eax==IDC_BTN2 ;取消 invoke SendMessage,hWnd,WM_CLOSE,0,0 .endif .elseif uMsg==WM_CLOSE invoke EndDialog,hWnd,wParam .else mov eax,FALSE ret .endif mov eax,TRUE ret DlgProc endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM local pt:POINT local @stStartInfo:STARTUPINFO local @stProcessInfo:PROCESS_INFORMATION mov eax,uMsg .if uMsg==WM_CREATE ;得到当前桌面 invoke GetCurrentThreadId invoke GetThreadDesktop,eax mov hCurrentDesktop,eax invoke SetWindowPos,hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE ;窗口置顶 invoke RegisterHotKey,hWnd,WIN0,MOD_WIN,VK_OEM_3 ;WIN+` VK_OEM_3 是 C0 不同的头文件有可能不同 就是1前面那个~ invoke CreatePopupMenu mov hPopupMenu,eax invoke AppendMenu,hPopupMenu,MF_STRING,IDM_ABOUT,addr szAboutString invoke AppendMenu,hPopupMenu,MF_STRING,IDM_HELP,addr szHelpString invoke AppendMenu,hPopupMenu,MF_STRING,IDM_SETTING,addr szSettingString invoke AppendMenu,hPopupMenu,MF_STRING,IDM_EXIT,addr szExitString mov note.cbSize,sizeof NOTIFYICONDATA_ push hWnd pop note.hwnd mov note.uID,IDI_TRAY mov note.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP mov note.uCallbackMessage,WM_SHELLNOTIFY invoke LoadIcon,hInstance,ICON_168 mov note.hIcon,eax invoke lstrcpy,addr note.szTip,offset szAppName invoke Shell_NotifyIcon,NIM_ADD,addr note push ecx invoke CreateThread,0,0,offset _CreateDesktop,0,0,esp pop ecx xor edi,edi .while edi < dwNewDesktopNum mov eax,edi add eax,031h invoke RegisterHotKey,hWnd,edi,MOD_WIN,eax ;WIN+1 到 WIN+9 inc edi .endw invoke lstrcpy,addr note.szInfo,offset szInitInfo invoke lstrcpy,addr note.szInfoTitle,offset szAppName mov eax,note.uFlags or eax,NIF_INFO mov note.uFlags,eax mov note.uTimeout,20d mov note.dwInfoFlags,NIIF_INFO invoke Shell_NotifyIcon,NIM_MODIFY,addr note ;防止外壳后图标消失 invoke RegisterWindowMessage,CTXT('TaskbarCreated') mov dwMsgTaskbarRestart,eax .elseif eax==dwMsgTaskbarRestart ;只能用这个笨办法了 赋给eax再比 mov note.uFlags,NIF_ICON+NIF_MESSAGE+NIF_TIP invoke Shell_NotifyIcon,NIM_ADD,addr note or note.uFlags,NIF_INFO mov eax,dwNewDesktopNum inc eax invoke wsprintf,addr note.szInfo,offset szFmtDesktopNum,eax invoke Shell_NotifyIcon,NIM_MODIFY,addr note .elseif uMsg==WM_DESTROY invoke DestroyMenu,hPopupMenu ;切回原来的 invoke SwitchDesktop,hCurrentDesktop invoke UnregisterHotKey,hWnd,WIN0 xor edi,edi .while edi < dwNewDesktopNum invoke UnregisterHotKey,hWnd,edi invoke wsprintf,offset szBuf,CTXT('MD_Desktop%d'),edi ;MD_Desktop0 到 MD_Desktop8 ;关掉已新建的桌面 ;桌面关了 但这个桌面的程序还在 所以 下次再有和这个名字相同的桌面时那些窗口应该还在 ;所以 可能会多一堆 我的文档 一类的窗口 故而 本程序一次只能运行一个 且不推荐改变桌面数 invoke OpenDesktop,offset szBuf,0,FALSE,0 .if !eax invoke CloseDesktop,eax .endif inc edi .endw invoke Shell_NotifyIcon,NIM_DELETE,addr note invoke PostQuitMessage,NULL .elseif uMsg==WM_COMMAND .if lParam==0 mov eax,wParam .if ax==IDM_ABOUT invoke GetDesktopWindow invoke MessageBox,eax,offset szAboutText,offset szAppName,0 .elseif ax ==IDM_EXIT invoke DestroyWindow,hWnd .elseif ax ==IDM_HELP invoke GetDesktopWindow invoke MessageBox,eax,offset szHelpText,offset szAppName,0 .elseif ax ==IDM_SETTING invoke DialogBoxParam,hInstance,IDD_DLG1,0,offset DlgProc,0 ;必须保证新建的线程在当前桌面没有窗口 在“干净”的线程中最好 ;不用线程ID 随便放 push ecx invoke CreateThread,0,0,offset _CreateDesktop,0,0,esp pop ecx mov eax,dwNewDesktopNum inc eax invoke wsprintf,addr note.szInfo,offset szFmtDesktopNum,eax invoke Shell_NotifyIcon,NIM_MODIFY,addr note .endif .endif .elseif uMsg==WM_SHELLNOTIFY .if wParam==IDI_TRAY .if lParam==WM_RBUTTONDOWN invoke GetCursorPos,addr pt invoke SetForegroundWindow,hWnd invoke TrackPopupMenu,hPopupMenu,TPM_RIGHTALIGN,pt.x,pt.y,NULL,hWnd,NULL invoke PostMessage,hWnd,WM_NULL,0,0 .elseif lParam==WM_LBUTTONDOWN invoke SendMessage,hWnd,WM_COMMAND,IDM_ABOUT,0 .endif .endif .elseif uMsg==WM_HOTKEY .if wParam == WIN0 invoke SwitchDesktop,hCurrentDesktop .elseif wParam >= WIN1 && wParam <= WIN9 mov edi,wParam lea esi,stDesktop assume esi:ptr NEWDESKTOP imul ebx,edi,sizeof NEWDESKTOP mov eax,[esi+ebx].hDesktop invoke SwitchDesktop,eax .if [esi+ebx].fIsShell == FALSE invoke wsprintf,offset szBuf,CTXT('MD_Desktop%d'),edi ;MD_Desktop0 到 MD_Desktop8 mov @stStartInfo.cb,sizeof STARTUPINFO lea ecx,szBuf mov @stStartInfo.lpDesktop,ecx mov @stStartInfo.dwFlags,STARTF_USESHOWWINDOW mov @stStartInfo.wShowWindow,SW_SHOWNORMAL ;如果多次执行则会产生一堆 我的文档 一类的窗口 invoke CreateProcess,NULL,CTXT('explorer'),NULL,NULL,TRUE,NULL,NULL,NULL,addr @stStartInfo,addr @stProcessInfo ;这两个句柄不用就关 invoke CloseHandle,@stProcessInfo.hProcess invoke CloseHandle,@stProcessInfo.hThread mov [esi+ebx].fIsShell,TRUE .endif assume esi:NOTHING .endif .else invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .endif xor eax,eax ret WndProc endp end start |
;作者:zklhp
;Email:zklhp@
;QQ:493165744
;最后更新:2009.12.27
;版权所有 转载请保持完整
;**************************************************************************************************************
放一下本09年的最后一个程序吧 Multi_Desktop v0.1 算是最初版
因为是自己想的 没什么参考 还很不完善 貌似还有错 望各位老大多多指点 多拍板砖~
程序+代码
只有本站会员才能查看附件,请 登录