;-memload.asm-v0.5----------------------------------------------------------- ; x86 - Dos & Win32 - Assembly Language Programming ; ; ; ; Written by: John A Lyons (megablast) ; ; Email : asm@megablast.8k.com ; ; Page : http://asmsource.8k.com/ ; ; Compiler : Masm32 v6.13 Microsoft Macro Assembler ; ; Tested : Win98SE,Win2000 ; ; Date : 14-Feb-2001 ; ; Purpose : Program that displays the Memory load in a graph, within a ; ; small window. Includes a menu to change the options. ; ; ; ; v0.1 : Basic features, including graph function and menu ; ; v0.2 Added icon in top of main window. ; ; (15-Feb) Moved timer action to top of checking. ; ; Fixed memory leak, not destroying DC and brushes in timer loop; ; v0.3 : 100% memory load produces graph line too big, fixed. ; ; (16-Feb) Saves window position and run count to registry. ; ; v0.4 : Fixed up link in About box, changes colour. ; ; (25-Feb) Added about menu option to system menu. ; ; v0.5 : Added ability to resize box, and it changes graph size. ; ; (26-Feb) limit width of box, so graph stays below 301. ; ; Save new size to registry. ; ; Added menu breaks, to pretty the popup menu. ; ; Added Win2000 compatability ; ; Fixed logical problem with graph resize, in the way that the ; ; load data was stored. Much better system now, that keeps ; ; 300 positions, irrelevant of the graph width. ; ; ; ;---------------------------------------------------------------------------- .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 include shell32.inc includelib shell32.lib include advapi32.inc includelib advapi32.lib EXTRN wsprintfA:PROC ; ---------- procedures declared later update proto :DWORD graph proto HyperLinkWndProc PROTO :HWND, :DWORD, :DWORD, :DWORD regget proto regstring:DWORD regset proto regstring:DWORD,number:DWORD .CONST IDI_ICON1 equ 5 IDC_TAB1 EQU 1011 ;------------------------- 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_update equ 2004 ;------------------------- About IDC_URL equ 9 IDI_CUR1 equ 101 IDI_BITMAP equ 102 .DATA wmenu dd ? MainDlgName DB "MAINWINDOW",0 aboutdialog DB "ABOUTDIALOG",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 ;TabTitle4 DB "About",0 windowtitle db "Memory Load",0 count dd 0 num1 db "%%" num2 db "%lu",0 hInstance HINSTANCE ? CommandLine LPSTR ? mem1 db "Load %%%lu",0 runcount1 db "RunCount %lu",0 buff db 256 dup(?) menuhand DWORD ? first BOOL FALSE ;------------------------- Options ontop BOOL FALSE windowupdate BOOL TRUE ;------------------------- Popup Menu IDM_ONTOP equ 2 IDM_UPDATE equ 3 ;IDM_EXIT equ 1 ;IDM_ABOUT equ 4 pick1 db "Always On Top",0 pick2 db "Update Title",0 about db "About",0 exit db "Exit",0 ;------------------------- About hover BOOL ? ;first BOOL FALSE szOpen db "open",0 hwndDlg dd 0 first2 BOOL FALSE hFinger dd ? orgStatic dd ? tabwin dd ? newload BOOL TRUE memoryload dd ? mainhwnd HANDLE ? ItemStruct TC_ITEM WhichTabChosen DWORD ? ;-------------------------------- Graph graphload db 1000 dup(?) graphsize dd 0 graphstart dd 0 graphheight dd 0 graphwidth dd 0 ;-------------------------------- Registry regstring2 db "Run Count",0 regstring1 db "xpos",0 regstring3 db "ypos",0 regheight db "height",0 regwidth db "width",0 subkeyname db "Software\memload",0 xpos dd NULL ypos dd NULL hBitmap dd ? IDB_MAIN equ 102 .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 eax,hInst mov hInstance,eax RET WinMain endp DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM LOCAL hdc:DWORD LOCAL rect:RECT LOCAL Disp :DWORD LOCAL pKey :DWORD LOCAL Temp :DWORD mov eax,uMsg ;handle timer event, put it first, since we ;want to handle it quickly. .if ax==WM_TIMER push ebx push edi push esi call updateload cmp newload,FALSE je noupdate cmp windowupdate,TRUE jne noupdate mov eax,[memoryload] push eax push offset mem1 push offset buff call wsprintfA add esp,0ch invoke SetWindowText,mainhwnd,ADDR buff noupdate: call graph pop esi pop edi pop ebx xor eax,eax ret ; .elseif ax==WM_NCHITTEST ; xor eax,eax ; ret ; .elseif ax==WM_MOUSEMOVE ; xor eax,eax ; ret ; .elseif ax==WM_SETCURSOR ; xor eax,eax ; ret .elseif ax==WM_CLOSE bigclose: invoke KillTimer,hWnd,ID_TIMER invoke GetWindowRect,hWnd,ADDR rect mov eax,rect.top mov eax,rect.left mov eax,[count] inc eax invoke regset,ADDR regstring2,eax mov eax,xpos invoke regset,ADDR regstring1,eax mov eax,ypos invoke regset,ADDR regstring3,eax mov eax,graphheight invoke regset,ADDR regheight,eax mov eax,graphwidth invoke regset,ADDR regwidth,eax INVOKE ExitProcess,0 RET ;deal with a move .ELSEIF ax==WM_MOVE call updatepos ;first things to do, seutp icon ;read registry,set window pos, create ;menu,change system menu, and setup ;timer event .elseif ax==WM_INITDIALOG push ebx invoke LoadIcon, hInstance, IDI_ICON1 invoke SendMessage, hWnd, WM_SETICON, 1, eax invoke LoadBitmap,hInstance,IDB_MAIN mov hBitmap,eax mov eax,hWnd mov mainhwnd,eax ;retreive pos invoke regget,ADDR regstring2 mov [count],eax invoke regget,ADDR regstring1 mov xpos,eax invoke regget,ADDR regstring3 mov ypos,eax ;retreive size invoke regget,ADDR regheight mov [graphheight],eax add eax,38 push eax invoke regget,ADDR regwidth pop ebx mov graphwidth,eax add eax,19 invoke SetWindowPos,mainhwnd,0,xpos,ypos,eax,ebx,SWP_NOZORDER+SWP_SHOWWINDOW invoke CreatePopupMenu mov [wmenu],eax mov eax,[count] push eax push offset runcount1 push offset buff call wsprintfA add esp,0ch invoke AppendMenu,wmenu,MF_STRING,-1,ADDR buff invoke AppendMenu,wmenu,MF_SEPARATOR,0,0 invoke AppendMenu,wmenu,MF_STRING,IDM_ONTOP,ADDR pick1 invoke AppendMenu,wmenu,MF_STRING,IDM_UPDATE,ADDR pick2 invoke AppendMenu,wmenu,MF_STRING,IDM_ABOUT,ADDR about invoke AppendMenu,wmenu,MF_SEPARATOR,0,0 invoke AppendMenu,wmenu,MF_STRING,IDM_EXIT,ADDR exit invoke CheckMenuItem,wmenu,IDM_UPDATE,MF_CHECKED invoke GetSystemMenu,hWnd,FALSE invoke AppendMenu,eax,MF_STRING,IDM_ABOUT,ADDR about call updatepos invoke SetTimer, mainhwnd, ID_TIMER, 1000, 0 pop ebx ;deal with menu commands .ELSEIF ax==WM_COMMAND mov eax,wParam .IF lParam==0 .IF ax==IDM_ONTOP xor ontop,1 cmp ontop,TRUE je setontop invoke SetWindowPos,mainhwnd,HWND_NOTOPMOST,0,0,0,0,SWP_NOMOVE+SWP_NOSIZE invoke CheckMenuItem,wmenu,IDM_ONTOP,MF_UNCHECKED jmp clearontop setontop: invoke SetWindowPos,mainhwnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE+SWP_NOSIZE invoke CheckMenuItem,wmenu,IDM_ONTOP,MF_CHECKED clearontop: .ELSEIF ax==IDM_UPDATE xor [windowupdate],1 cmp [windowupdate],TRUE je setupdate invoke SetWindowText,mainhwnd,ADDR windowtitle invoke CheckMenuItem,wmenu,IDM_UPDATE,MF_UNCHECKED jmp noupdate1 setupdate: mov [memoryload],0 invoke CheckMenuItem,wmenu,IDM_UPDATE,MF_CHECKED noupdate1: .ELSEIF ax==IDM_ABOUT goabout: lea eax,AboutDlgProc invoke CreateDialogParam,hInstance,addr aboutdialog,hWnd,eax,NULL mov hwndDlg,eax .ELSEIF ax==IDM_EXIT jmp bigclose .ENDIF .ENDIF ;deal with command from system menu .ELSEIF ax==WM_SYSCOMMAND mov eax,wParam .IF ax==IDM_ABOUT jmp goabout .endif ;when we need to repaint .elseif ax==WM_PAINT push ebx push edi push esi call graph pop esi pop edi pop ebx .elseif ax==WM_SIZE ;someone trying to resize window, ;just stop them from making it too big. invoke GetWindowRect,mainhwnd,ADDR rect mov eax,rect.bottom sub eax,rect.top sub eax,38 mov [graphheight],eax mov eax,rect.right sub eax,rect.left sub eax,19 mov [graphwidth],eax cmp eax,300-9 ; is our window too big??? jb sizeok2 mov eax,[graphheight] add eax,38 invoke SetWindowPos,mainhwnd,0,xpos,ypos,299,eax,SWP_NOZORDER+SWP_SHOWWINDOW sizeok2: ;popup menu .ELSEIF ax==WM_RBUTTONDOWN mov edx,lParam mov ecx,edx and edx,0ffffh shr ecx,16 add edx,xpos add ecx,ypos add ecx,20 invoke TrackPopupMenu,wmenu,TPM_CENTERALIGN +TPM_LEFTBUTTON,edx,ecx,0,hWnd,NULL .endif xor eax,eax ret DlgProc endp updatepos proc LOCAL rect:RECT invoke GetWindowRect,mainhwnd,ADDR rect mov eax,rect.top mov ypos,eax mov eax,rect.left mov xpos,eax ret updatepos endp AboutDlgProc PROC hWnd:HWND,iMsg:DWORD,wParam:WPARAM, lParam:LPARAM LOCAL hdc:DWORD LOCAL ps:PAINTSTRUCT LOCAL rect:RECT mov eax,iMsg .if eax==WM_INITDIALOG invoke GetDlgItem, hWnd, IDC_URL invoke SetWindowLong, eax, GWL_WNDPROC, ADDR HyperLinkWndProc mov orgStatic,eax invoke LoadCursor,hInstance,IDI_CUR1 mov hFinger,eax push count push offset runcount1 push offset buff call wsprintfA add esp,0ch invoke SendDlgItemMessage, hWnd, IDD_LOAD, WM_SETTEXT, 0,ADDR buff xor eax,eax ret .ELSEIF eax == WM_CTLCOLORSTATIC invoke SendMessage,lParam,iMsg,wParam,lParam ret .elseif eax==WM_CLOSE invoke EndDialog,hWnd,NULL mov hwndDlg,0 .elseif eax==WM_COMMAND push edx mov eax,wParam mov edx,eax shr edx,16 .if eax==IDC_EXIT invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL invoke EndDialog,hWnd,NULL mov hwndDlg,0 .endif pop edx .else mov eax,FALSE ret .endif mov eax,TRUE ret AboutDlgProc endp aAboutDlgProc PROC hWnd:HWND,iMsg:DWORD,wParam:WPARAM, lParam:LPARAM LOCAL hdc:DWORD LOCAL ps:PAINTSTRUCT LOCAL rect:RECT mov eax,iMsg .if eax==WM_INITDIALOG pusha invoke GetDlgItem, hWnd, IDC_URL invoke SetWindowLong, eax, GWL_WNDPROC, ADDR HyperLinkWndProc mov orgStatic,eax invoke LoadCursor,hInstance,IDI_CUR1 mov hFinger,eax push count push offset runcount1 push offset buff call wsprintfA add esp,0ch invoke SendDlgItemMessage, hWnd, IDD_LOAD, WM_SETTEXT, 0,ADDR buff popa .ELSEIF eax == WM_CTLCOLORSTATIC invoke SendMessage,lParam,iMsg,wParam,lParam .elseif eax==WM_CLOSE invoke EndDialog,hWnd,NULL mov hwndDlg,0 .elseif eax==WM_COMMAND push edx mov eax,wParam mov edx,eax shr edx,16 .if eax==IDC_EXIT invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL invoke EndDialog,hWnd,NULL mov hwndDlg,0 .endif .else pop edx mov eax,FALSE ret .endif mov eax,TRUE ret aAboutDlgProc endp HyperLinkWndProc PROC uses ebx, hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD LOCAL tmpFont :LOGFONT LOCAL rect:RECT LOCAL pt:POINT LOCAL ps:PAINTSTRUCT mov eax,uMsg .IF eax==WM_NCHITTEST mov eax, 1 ;We want to handle the non client hit test so we return true or 1 ret .ELSEIF eax == WM_CTLCOLORSTATIC push ebx push edx invoke SendMessage, hWnd, WM_GETFONT, 0, 0 mov edx,eax invoke GetObject, edx, sizeof LOGFONT, addr tmpFont mov tmpFont.lfUnderline, TRUE invoke CreateFontIndirect, addr tmpFont mov ebx,eax invoke SelectObject, wParam, ebx .if hover == FALSE invoke SetTextColor, wParam, Blue .else invoke SetTextColor, wParam,Red .endif invoke GetSysColor, COLOR_MENU invoke SetBkColor, wParam, eax invoke DeleteObject,ebx invoke GetStockObject, HOLLOW_BRUSH pop edx pop ebx ret .ELSEIF eax==WM_MOUSEMOVE invoke GetParent,hWnd push ebx mov ebx,eax invoke GetActiveWindow .if eax == ebx invoke GetCursorPos,addr pt invoke GetWindowRect,hWnd,addr rect invoke PtInRect,addr rect,pt.x,pt.y .if eax invoke GetCapture .if !eax invoke SetCapture,hWnd mov hover,TRUE invoke InvalidateRect,hWnd,FALSE,FALSE invoke SetCursor,hFinger .endif .else invoke GetCapture .if eax invoke ReleaseCapture mov hover,FALSE invoke InvalidateRect,hWnd,FALSE,FALSE .endif .endif .endif pop ebx xor eax,eax ret .ELSEIF eax==WM_LBUTTONDOWN invoke GetWindowText,hWnd,offset buff,sizeof buff ;change this for using a preset url invoke ShellExecute, NULL, offset szOpen, offset buff, NULL, NULL, SW_MAXIMIZE ;change this to represent your preset url mov hover,FALSE invoke InvalidateRect,hWnd,FALSE,FALSE invoke SendMessage, hWnd, WM_GETFONT, 0, 0 ;Get the defualt system font mov edx,eax ;store result invoke GetObject, edx, sizeof LOGFONT, addr tmpFont ;get our font into a logfont structure mov tmpFont.lfUnderline, TRUE ;under line the link invoke CreateFontIndirect, addr tmpFont ;Create the new font mov ebx,eax ;We need the return to free the memory later invoke SelectObject, wParam, ebx ;Select our control invoke SetTextColor, wParam, Blue ;change this to change the color of the link xor eax,eax ret .ENDIF invoke CallWindowProc, orgStatic, hWnd, uMsg, wParam, lParam ret HyperLinkWndProc endp updateload proc LOCAL mst:MEMORYSTATUS invoke GlobalMemoryStatus,ADDR mst mov eax,mst.dwMemoryLoad cmp eax,[memoryload] je notnewload1 mov [memoryload],eax mov [newload],TRUE jmp newload1 notnewload1: mov [newload],FALSE newload1: lea esi,graphload mov ebx,[graphsize] cmp ebx,300 jb domaths mov ebx,[graphstart] inc [graphstart] cmp [graphstart],300 jne nomaths mov [graphstart],0 jmp nomaths domaths: inc [graphsize] nomaths: add esi,ebx mov [esi],al ret updateload endp graph proc LOCAL hdc:HWND LOCAL ps:PAINTSTRUCT LOCAL brush:HBRUSH LOCAL object:HBRUSH LOCAL hMemDC:HDC LOCAL rect:RECT invoke GetDC,mainhwnd mov hdc,eax invoke CreateSolidBrush,0ff0000h invoke SelectObject,hdc,eax mov edx,[graphwidth] add edx,7+4 mov ecx,[graphheight] add ecx,7+4 invoke Rectangle,hdc,0,0,edx,ecx invoke SelectObject,hdc,object invoke DeleteObject,eax invoke CreatePen,PS_SOLID,1,0ffffffh mov brush,eax invoke SelectObject,hdc,eax mov object,eax push edi push esi mov ecx,[graphsize] cmp ecx,0 je noplay lea esi,graphload mov edi,1 ;top cmp [graphstart],0 je startsimple mov eax,[graphstart] mov ebx,[graphwidth] add ebx,9 cmp eax,ebx jb nojohn1 sub eax,ebx jmp gook1 nojohn1: add eax,300 sub eax,ebx gook1: add esi,eax jmp next2 startsimple: mov eax,[graphwidth] add eax,9 cmp ecx,eax jbe nextrect mov ebx,[graphsize] sub ebx,eax add esi,ebx next2: mov ecx,[graphwidth] add ecx,9 nextrect: xor eax,eax mov al,[esi] xor edx,edx mov ebx,[graphheight];52 add ebx,9 mul ebx xor edx,edx mov ebx,100 div ebx mov ebx,[graphheight];58 add ebx,10 cmp eax,ebx jbe subok1 mov eax,ebx subok1: sub ebx,eax mov eax,edi inc eax push esi push edi push ecx mov ecx,[graphheight] add ecx,6+4 invoke Rectangle,hdc,edi,ebx,eax,ecx;58 pop ecx pop edi pop esi inc esi inc edi lea eax,graphload add eax,300;[graphwidth];225 cmp esi,eax jb graphok lea esi,graphload graphok: loop nextrect noplay: invoke SelectObject,hdc,object invoke DeleteObject,brush pop esi pop edi invoke ReleaseDC,mainhwnd,hdc ret graph endp regget proc regstring:DWORD LOCAL number:DWORD LOCAL Disp :DWORD LOCAL pKey :DWORD LOCAL Temp :DWORD mov Temp,4 invoke RegCreateKeyEx, HKEY_LOCAL_MACHINE,ADDR subkeyname, NULL, NULL,REG_OPTION_NON_VOLATILE,KEY_READ, NULL,addr pKey, addr Disp cmp eax,ERROR_SUCCESS jne regok1 invoke RegQueryValueEx, pKey, regstring,NULL, ADDR Disp, ADDR number, ADDR Temp invoke RegCloseKey, pKey mov eax,number ret regok1: mov eax,NULL ret regget endp regset proc regstring:DWORD,number:DWORD LOCAL Disp :DWORD LOCAL pKey :DWORD LOCAL Temp :DWORD mov Temp,4 invoke RegCreateKeyEx, HKEY_LOCAL_MACHINE,ADDR subkeyname, NULL, NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE, NULL, addr pKey, addr Disp cmp eax,ERROR_SUCCESS jne regok2 invoke RegSetValueEx, pKey, regstring,NULL, REG_DWORD_LITTLE_ENDIAN,ADDR number, Temp invoke RegCloseKey, pKey regok2: ret regset endp END start