;运行效果
;win32汇编环境,窗口程序中使用IP地址控件示例
;演示了如何设置IP控件的IP地址,取得IP控件的地址值的操作,并解释了其原理
;也可以使用编辑框控件代替,但是需要写更多的东西,比如需要输入数值是否超255,需要进行窗口的子类化,但IP地址控件不用,它已经封装了这些自检功能
;直接抄进RadAsm可编译运行。重要部分加备注。
;下面为asm文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
;Equ 等值定义
IDC_IP equ 1001 ;IP控件标识符
ButtonID equ 1002
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.DATA
ClassName db "SimpleWinClass",0
AppName db "窗口程序的模版",0
szMsg db "提示",0
szFMR db "取得的IP地址是 %d.%d.%d.%d",0
szSTClassName db "static",0 ;静态控件类名
szSTCaption db "IP地址控件示例:",0
szIPClassName db "SysIPAddress32",0 ;IP控件类名
szButtonClassName db "button",0 ;按钮类名
szButtonTitle db "取得IP地址值",0
.DATA?
hInstance HINSTANCE ?
CommandLine LPSTR ?
hIDC_IP HWND ? ;IP控件句柄
hButton HWND ?
nGetIP LPARAM ? ;存放从IP地址控件取得的值的指针
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.CODE
start:
invoke GetModuleHandle, NULL
mov hInstance,eax
invoke GetCommandLine
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess, eax
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hwnd:HWND
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WndProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET ClassName
invoke LoadIcon,NULL,IDI_APPLICATION
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc
invoke CreateWindowEx,NULL, ADDR ClassName,ADDR AppName,WS_OVERLAPPEDWINDOW,100,100,330,180, NULL,NULL,hInst, NULL
mov hwnd,eax
invoke ShowWindow, hwnd,CmdShow
invoke UpdateWindow, hwnd
.while TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.break .if (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.endw
mov eax,msg.wParam
ret
WinMain endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL @szBuffer[256]:byte
LOCAL @IP_addr1,@IP_addr2,@IP_addr3,@IP_addr4
.if uMsg == WM_CREATE
invoke CreateWindowEx,NULL,ADDR szSTClassName,ADDR szSTCaption, WS_CHILD + WS_VISIBLE,20, 30, 150, 30,hWnd,NULL,NULL,NULL ;创建静态控件,用来显示文本
invoke CreateWindowEx,NULL,ADDR szIPClassName,NULL, WS_CHILDWINDOW+WS_VISIBLE+WS_EX_DLGMODALFRAME,135,25,150,25,hWnd,IDC_IP,NULL,NULL ;创建IP地址控件
mov hIDC_IP,eax
invoke CreateWindowEx,NULL,ADDR szButtonClassName,ADDR szButtonTitle, WS_TABSTOP OR WS_VISIBLE OR WS_CHILD OR BS_DEFPUSHBUTTON ,60,80,200,25,hWnd,ButtonID,NULL,NULL ;创建按钮控件
mov hButton,eax
;IP地址控件内的值,是1个32位的数。其中每8位占一个值,最高的字节为IP地址的开头值,最低的字节为结束值。以下面的IP地址:192.168.1.1为例。
;先把低2个字节的值即192和168赋值,然后用 shl 指令往左移位16位,就是占了高2位字节的位置,再把IP地址的后面两个值给它加上
mov ah,192
mov al,168
shl eax,16
mov ah,1
mov al,1
invoke SendMessage,hIDC_IP,IPM_SETADDRESS,0,eax ;初始化设置控件里的IP地址值
.elseif uMsg == WM_COMMAND
mov eax,wParam
.if ax == ButtonID
;以下是如何取得IP控件的地址值,IPM_GETADDRESS消息是取得地址值,但是它会放在一个所指向的DOWRD值的指针里。下面的 nGetIP 得到的值是一个指针,是一个指向某个DWORD的值的指针,并不是IP地址值,这个DWORD的值才是IP地址值
;所以要通过这个指针得到IP地址值的每个字段的数值
;就是说,这个nGetIP指向的内存地址里,有一个4字节的值,这个值就是IP控件的地址值
;然后,我们按字节取出值,比如这里的示例192.168.1.1,左边的是高字节,右边的是低字节
invoke SendMessage,hIDC_IP,IPM_GETADDRESS,0,offset nGetIP ;取出IP地址控件里的值的指针,并把这个指针值放在nGetIP里
mov bl,byte ptr [nGetIP+3] ;取出192这个值
movzx ebx,bl ;把ebx里面除了bl的值外都置0,因为不清楚bl前面的值是什么
mov @IP_addr1,ebx
mov bl,byte ptr [nGetIP+2] ;取出168这个值,后面以此类推
movzx ebx,bl
mov @IP_addr2,ebx
mov bl,byte ptr [nGetIP+1]
movzx ebx,bl
mov @IP_addr3,ebx
mov bl,byte ptr [nGetIP]
movzx ebx,bl
mov @IP_addr4,ebx
invoke wsprintf,addr @szBuffer,addr szFMR, @IP_addr1,@IP_addr2,@IP_addr3,@IP_addr4
invoke MessageBox,NULL,addr @szBuffer,addr szMsg,MB_OK
.endif
.elseif uMsg == WM_DESTROY
invoke PostQuitMessage,NULL
.else
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.endif
xor eax,eax
ret
WndProc endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start