;-memgraph.asm-v0.1---------------------------------------------------------- ; x86 - Dos & Win32 - Assembly Language Programming ; ; ; ; Written by: John A Lyons ; ; Email : sysop@megablast.8k.com ; ; Page : http://www.asmsource.8k.com/ ; ; Compiler : Masm32 v6.13 Microsoft Macro Assembler ; ; Date : 13-Feb-2001 ; ; Purpose : Program that displays information about memory. User a timer ; ; interrupt to update, and a dialog box as the main window. Also; ; Changes the window text so that load is updated in taskbar. ; ; Includes tab control to swith between stats, a graph and ; ; options. ; ; ; ; Thanks to 'RAZOR'X and his program mem-info and Latigo for ; ; his program Tab Control. ; ; ; ; v0.1 : basic features, including graph function, radio buttons dont ; ; work yet ; ; ; ;---------------------------------------------------------------------------- .386 .MODEL FLAT, STDCALL include windows.inc include user32.inc include kernel32.inc include comctl32.inc include gdi32.inc includelib kernel32.lib includelib user32.lib includelib comctl32.lib includelib gdi32.lib EXTRN wsprintfA:PROC ; procedures declared later update proto :DWORD graph proto .CONST IDC_TAB1 EQU 1011 ; The Tab Control identifier ;------------------------- buttons IDC_EXIT equ 3002 IDC_HIDE equ 3000 ;------------------------- timer ID_TIMER equ 400 ;------------------------- menu IDM_FAST equ 32000 IDM_SLOW equ 32001 IDM_EXIT equ 32003 IDM_ABOUT equ 32002 ;------------------------- dialog IDD_TPYHS equ 501 IDD_APYHS equ 502 IDD_APAGE equ 504 IDD_TPAGE equ 503 IDD_AVIRT equ 505 IDD_TVIRT equ 506 IDD_LOAD equ 507 ;------------------------- Options IDC_ALWAYS equ 2000 ;IDC_RADIO1 equ 2001 ;IDC_RADIO2 equ 2002 ;IDC_RADIO3 equ 2003 IDC_FAST equ 2001 IDC_MED equ 2002 IDC_SLOW equ 2003 IDC_CANTMOVE equ 2004 .DATA MainDlgName DB "IDD_DIALOG1",0 Child1Name DB "IDD_CHILD1",0 Child2Name DB "IDD_CHILD2",0 Child3Name DB "IDD_CHILD3",0 TabTitle1 DB "Memory",0 TabTitle2 DB "Graph",0 TabTitle3 DB "Options",0 count dd 0 num1 db "%%" num2 db "%lu",0 hInstance HINSTANCE ? CommandLine LPSTR ? mem1 db "Mem Load %%%lu",0 buff db 256 dup(?) menuhand DWORD ? first BOOL FALSE ;------------------------- Options ontop BOOL FALSE windowmove BOOL FALSE tabwin dd ? memoryload dd ? mainhwnd HANDLE ? hwndTab HANDLE ? Handles LABEL DWORD Child1hWnd HANDLE ? Child2hWnd HANDLE ? Child3hWnd HANDLE ? ItemStruct TC_ITEM WhichTabChosen DWORD ? ;graph data graphload dd 100 dup(?) graphsize dd 0 graphstart dd 0 .CODE start: WinMain PROTO hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdShow:SDWORD INVOKE GetModuleHandle, NULL MOV hInstance,EAX INVOKE WinMain, hInstance,NULL,SW_SHOWDEFAULT INVOKE ExitProcess,EAX WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdShow:SDWORD MOV EAX, OFFSET DlgProc INVOKE DialogBoxParam, hInst, OFFSET MainDlgName,NULL,EAX,NULL ;mov mainhwnd,eax mov eax,hInst mov hInstance,eax RET WinMain endp DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hdc:DWORD LOCAL ps:PAINTSTRUCT MOV EAX,uMsg .if eax==WM_CLOSE INVOKE ExitProcess,0 RET .elseif eax==WM_INITDIALOG mov eax,hWnd mov mainhwnd,eax INVOKE InitCommonControls INVOKE GetDlgItem,hWnd,IDC_TAB1 MOV hwndTab,EAX MOV ItemStruct.imask,TCIF_TEXT MOV ItemStruct.lpReserved1,0 MOV ItemStruct.lpReserved2,0 MOV ItemStruct.pszText,OFFSET TabTitle1 MOV ItemStruct.cchTextMax,sizeof TabTitle1 MOV ItemStruct.iImage,0 MOV ItemStruct.lParam,0 INVOKE SendMessage,hwndTab,TCM_INSERTITEM,0,OFFSET ItemStruct MOV ItemStruct.pszText,OFFSET TabTitle2 MOV ItemStruct.cchTextMax,sizeof TabTitle2 INVOKE SendMessage,hwndTab,TCM_INSERTITEM,1,OFFSET ItemStruct MOV ItemStruct.pszText,OFFSET TabTitle3 MOV ItemStruct.cchTextMax,sizeof TabTitle3 INVOKE SendMessage,hwndTab,TCM_INSERTITEM,2,OFFSET ItemStruct MOV EAX,OFFSET TextDlgProc INVOKE CreateDialogParam,hInstance,OFFSET Child1Name,hwndTab,EAX,0 MOV Child1hWnd,EAX MOV EAX,OFFSET GraphDlgProc INVOKE CreateDialogParam,hInstance,OFFSET Child2Name,hwndTab,EAX,0 MOV Child2hWnd,EAX MOV EAX,OFFSET OptionsDlgProc INVOKE CreateDialogParam,hInstance,OFFSET Child3Name,hwndTab,EAX,0 MOV Child3hWnd,EAX MOV WhichTabChosen,0 ; lets initialize our variable with 0, since we will start showing the ; first child dialogbox and its index is 0. INVOKE ShowWindow,Child1hWnd,SW_SHOWDEFAULT ; Here we show the recently created child dialog box ;invoke update,Child1hWnd invoke SetTimer, mainhwnd, ID_TIMER, 1000, 0 RET .elseif eax==WM_COMMAND MOV EAX,wParam RET .elseif eax==WM_NOTIFY MOV EAX,lParam MOV EAX, (NMHDR PTR [eax]).code CMP EAX, TCN_SELCHANGE JZ ChangingTab RET ChangingTab: MOV EBX,WhichTabChosen MOV EAX,[Handles+EBX*4] INVOKE ShowWindow,EAX,SW_HIDE INVOKE SendMessage,hwndTab,TCM_GETCURSEL,0,0 ; Ok which one is BEING chosen right now? MOV WhichTabChosen,EAX MOV EBX,[Handles+EAX*4] mov tabwin,ebx INVOKE ShowWindow,EBX,SW_SHOWDEFAULT ;invoke update,tabwin ; .elseif eax==WM_MOUSEMOVE ;invoke GetDC,mainhwnd ;mov hdc,eax ;invoke Rectangle,hdc,50,50,60,80 ;invoke EndPaint,mainhwnd, ADDR ps .ELSEIF uMsg==WM_TIMER call updateload ; inc count ; mov eax,count ; push eax ; push offset num2 ; push offset buff ; call wsprintfA ; add esp,0ch ;invoke update,NULL mov eax,[memoryload] push eax push offset mem1 push offset buff call wsprintfA add esp,0ch invoke SetWindowText,mainhwnd,ADDR buff ;invoke Rectangle,mainhwnd,20,15,232,89 ;invoke SendMessage,Child2hWnd,WM_PAINT,0,0 cmp [WhichTabChosen],0 je nograph call graph ;invoke InvalidateRect,Child2hWnd,NULL,TRUE jmp graph22 nograph: invoke InvalidateRect,Child1hWnd,NULL,TRUE invoke update,Child2hWnd graph22: .endif xor EAX,EAX RET DlgProc endp GraphDlgProc PROC SmallhWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hdc:DWORD LOCAL ps:PAINTSTRUCT ;window size 10,25 - 402,166 h,140 w = 330 xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax MOV EAX,uMsg ; ret .if eax==WM_INITDIALOG ;invoke Rectangle,mainhwnd,20,15,232,89 ;invoke GetDC,hwndTab ;mov hdc,eax ;invoke Rectangle,hdc,50,50,60,80 ;invoke EndPaint,hwndTab, ADDR ps ;invoke update,NULL ;call graph ; .elseif eax==WM_ERASEBKGND ; ret .elseif eax==WM_CTLCOLORSTATIC;WM_PAINT ;invoke InvalidateRect,Child2hWnd,NULL,TRUE ;invoke update,NULL call graph .endif XOR EAX,EAX RET GraphDlgProc ENDP TextDlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .if uMsg==WM_INITDIALOG;WM_GETMINMAXINFO ; 24 cmp first,FALSE jne nob1 invoke GetMenu,hWnd mov menuhand,eax invoke SetTimer, tabwin, ID_TIMER, 1000, 0 mov first,TRUE inc count mov eax,count push eax push offset num2 push offset buff call wsprintfA add esp,0ch ; invoke update,hwndTab ; invoke SetWindowText,mainhwnd,ADDR buff invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .elseif uMsg==WM_PAINT invoke update,Child1hWnd;hwndTab ret .ELSEIF uMsg==WM_DESTROY ;invoke KillTimer,hWnd,ID_TIMER invoke PostQuitMessage,NULL ret .ELSEIF uMsg==WM_COMMAND mov eax,wParam .IF lParam==0 .IF ax==IDM_EXIT invoke DestroyWindow,hWnd ret .ELSEIF ax==IDM_SLOW invoke CheckMenuItem,menuhand,IDM_SLOW,MF_CHECKED invoke CheckMenuItem,menuhand,IDM_FAST,MF_UNCHECKED invoke KillTimer,hWnd,ID_TIMER invoke SetTimer, hWnd, ID_TIMER, 60000, 0 .ELSEIF ax==IDM_FAST invoke CheckMenuItem,menuhand,IDM_SLOW,MF_UNCHECKED invoke CheckMenuItem,menuhand,IDM_FAST,MF_CHECKED invoke KillTimer,hWnd,ID_TIMER invoke SetTimer, hWnd, ID_TIMER, 5000, 0 .ELSEIF ax==IDM_ABOUT ; invoke CreateDialogParam,hInstance, addr AbtName,hWnd,OFFSET DlgProc,NULL ; mov hwndDlg,eax .ENDIF .ELSE .IF ax==IDC_EXIT invoke SendMessage,hWnd,WM_COMMAND,IDM_EXIT,0 ret .ELSEIF ax==IDC_HIDE invoke ShowWindow,mainhwnd,SW_MINIMIZE ret .ENDIF .ENDIF .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .ENDIF nob1: xor eax,eax ret TextDlgProc endp update proc hWnd:HWND LOCAL mst:MEMORYSTATUS ;typedef struct _MEMORYSTATUS { // mst ; ; DWORD dwLength; // sizeof(MEMORYSTATUS) ; DWORD dwMemoryLoad; // percent of memory in use ; DWORD dwTotalPhys; // bytes of physical memory ; DWORD dwAvailPhys; // free physical memory bytes ; DWORD dwTotalPageFile; // bytes of paging file ; DWORD dwAvailPageFile; // free bytes of paging file ; DWORD dwTotalVirtual; // user bytes of address space ; DWORD dwAvailVirtual; // free user bytes ;} MEMORYSTATUS, *LPMEMORYSTATUS; invoke GlobalMemoryStatus,ADDR mst mov eax,mst.dwTotalPhys push eax push offset num2 push offset buff call wsprintfA add esp,0ch invoke SendDlgItemMessage, hWnd, IDD_TPYHS, WM_SETTEXT, 0,ADDR buff mov eax,mst.dwAvailPhys push eax push offset num2 push offset buff call wsprintfA add esp,0ch invoke SendDlgItemMessage, hWnd, IDD_APYHS, WM_SETTEXT, 0,ADDR buff mov eax,mst.dwTotalPageFile push eax push offset num2 push offset buff call wsprintfA add esp,0ch invoke SendDlgItemMessage, hWnd, IDD_TPAGE, WM_SETTEXT, 0,ADDR buff mov eax,mst.dwAvailPageFile push eax push offset num2 push offset buff call wsprintfA add esp,0ch invoke SendDlgItemMessage, hWnd, IDD_APAGE, WM_SETTEXT, 0,ADDR buff mov eax,mst.dwTotalVirtual push eax push offset num2 push offset buff call wsprintfA add esp,0ch invoke SendDlgItemMessage, hWnd, IDD_TVIRT, WM_SETTEXT, 0,ADDR buff mov eax,mst.dwAvailVirtual push eax push offset num2 push offset buff call wsprintfA add esp,0ch invoke SendDlgItemMessage, hWnd, IDD_AVIRT, WM_SETTEXT, 0,ADDR buff push mst.dwMemoryLoad push offset num1 push offset buff call wsprintfA add esp,0ch invoke SendDlgItemMessage, hWnd, IDD_LOAD, WM_SETTEXT, 0,ADDR buff ret update endp updateload proc LOCAL mst:MEMORYSTATUS invoke GlobalMemoryStatus,ADDR mst mov eax,mst.dwMemoryLoad mov [memoryload],eax lea esi,graphload;mov memoryload,eax mov ebx,graphsize cmp ebx,79 jb domaths mov ebx,[graphstart] inc [graphstart] cmp [graphstart],40 jne nomaths mov [graphstart],0 jmp nomaths domaths: inc [graphsize] nomaths: shl ebx,2 add esi,ebx mov [esi],eax ret updateload endp graph proc LOCAL hdc:HWND LOCAL ps:PAINTSTRUCT LOCAL brush:HBRUSH ;window size 10,25 - 402,166 h,140 w = 330 invoke GetDC,Child2hWnd;mainhwnd mov hdc,eax invoke CreateSolidBrush,0ff0000h invoke SelectObject,hdc,eax push eax invoke Rectangle,hdc,16,22,334,134 pop eax invoke DeleteObject,eax invoke CreateSolidBrush,0ffffffh invoke SelectObject,hdc,eax mov brush,eax push edi push esi mov ecx,[graphsize] cmp ecx,0 je noplay lea esi,graphload mov edi,17 ;top cmp [graphstart],0 je nextrect mov eax,[graphstart] shl eax,2 add esi,eax nextrect: mov eax,[esi] xor edx,edx mov ebx,111 mul ebx xor edx,edx mov ebx,100 div ebx mov ebx,133 sub ebx,eax mov eax,edi add eax,4 push esi push edi push ecx invoke Rectangle,hdc,edi,ebx,eax,133 pop ecx pop edi pop esi add esi,4 add edi,4 lea eax,graphload add eax,82*4 cmp esi,eax jb graphok lea esi,graphload graphok: loop nextrect noplay: invoke DeleteObject,brush pop esi pop edi invoke EndPaint,mainhwnd, ADDR ps ret graph endp OptionsDlgProc PROC SmallhWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hdc:DWORD LOCAL ps:PAINTSTRUCT LOCAL winrect:RECT ;window size 10,25 - 402,166 h,140 w = 330 MOV EAX,uMsg xor eax,eax .if eax==WM_INITDIALOG .elseif eax==WM_PAINT ;invoke InvalidateRect,Child2hWnd,NULL,TRUE ;invoke update,NULL .ELSEIF uMsg==WM_COMMAND mov eax,wParam .IF eax==IDC_ALWAYS xor ontop,1 ; invoke GetWindowRect,mainhwnd,ADDR winrect cmp ontop,TRUE je setontop ; invoke SetWindowPos,mainhwnd,HWND_NOTOPMOST,winrect.left,winrect.top,winrect.right,winrect.bottom,SWP_NOMOVE invoke SetWindowPos,mainhwnd,HWND_NOTOPMOST,200,200,417,202,SWP_NOMOVE jmp clearontop setontop: invoke SetWindowPos,mainhwnd,HWND_TOPMOST,200,200,417,202,SWP_NOMOVE ; invoke SetWindowPos,mainhwnd,HWND_TOPMOST,winrect.left,winrect.top,winrect.right,winrect.bottom,SWP_NOMOVE clearontop: .elseif eax==IDC_ALWAYS xor windowmove,1 cmp windowmove,TRUE je setmove invoke SetWindowPos,mainhwnd,SWP_NOMOVE,200,200,417,202,SWP_NOMOVE jmp setnomove setmove: ; invoke SetWindowPos,mainhwnd,SWP_MOVE,200,200,417,202,SWP_NOMOVE setnomove: .elseif eax==IDC_FAST invoke SetTimer, mainhwnd, ID_TIMER, 1000, 0 invoke CheckRadioButton,mainhwnd,IDC_FAST,IDC_SLOW,IDC_SLOW .elseif eax==IDC_MED invoke SetTimer, mainhwnd, ID_TIMER, 10000, 0 .elseif eax==IDC_SLOW invoke SetTimer, mainhwnd, ID_TIMER, 60000, 0 .endif .endif XOR EAX,EAX RET OptionsDlgProc ENDP END start