VC高手请进

[复制链接]
查看11 | 回复0 | 2007-7-29 18:09:56 | 显示全部楼层 |阅读模式
一个创建窗口的程序,是用汇编语言写的,其实用控制台写窗口主要就是定义好窗口类,注册窗口类,在窗口的回调函数里写好消息响应就可以了 .386 .model flat, stdcall option casemap :none ; case sensitive include windows.inc include user32.inc include kernel32.inc include comctl32.inc include comdlg32.inc include gdi32.inc includelib user32.lib includelib kernel32.lib includelib comctl32.lib includelib comdlg32.lib includelib gdi32.lib IDI_MAIN equ 1000 ;icon IDM_MAIN equ 4000 ;menu IDM_EXIT equ 4001 .data? hInstance dd ? hWinMain dd ? hMenu dd ? szBuffer db 256 dup (?) .data szClassName db "Windows Template",0 szCaptionMain db '窗口模板',0 .code start: call _WinMain invoke ExitProcess,NULL _WinMain proc local @stWcMain:WNDCLASSEX local @stMsg:MSG invoke InitCommonControls invoke GetModuleHandle,NULL mov hInstance,eax invoke LoadIcon,hInstance,IDI_MAIN mov hIcon,eax invoke LoadMenu,hInstance,IDM_MAIN mov hMenu,eax ;*************** 注册窗口类 invoke LoadCursor,0,IDC_ARROW mov @stWcMain.hCursor,eax mov @stWcMain.cbSize,sizeof WNDCLASSEX mov @stWcMain.hIconSm,0 mov @stWcMain.style,CS_HREDRAW or CS_VREDRAW mov @stWcMain.lpfnWndProc,offset WndMainProc mov @stWcMain.cbClsExtra,0 mov @stWcMain.cbWndExtra,0 mov eax,hInstance mov @stWcMain.hInstance,eax mov @stWcMain.hIcon,0 mov @stWcMain.hbrBackground,COLOR_WINDOW + 1 mov @stWcMain.lpszClassName,offset szClassName mov @stWcMain.lpszMenuName,0 invoke RegisterClassEx,addr @stWcMain ;*************** 建立输出窗口 invoke CreateWindowEx,WS_EX_CLIENTEDGE, offset szClassName,offset szCaptionMain, WS_OVERLAPPEDWINDOW OR WS_VSCROLL OR WS_HSCROLL, 0,0,550,300, NULL,hMenu,hInstance,NULL 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 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WndMainProc proc uses ebx edi esi, hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD mov eax,uMsg .if eax == WM_CREATE mov eax,hWnd mov hWinMain,eax call _Init ;*************************************************** .elseif eax == WM_COMMAND .if lParam == 0 mov eax,wParam .if ax == IDM_EXIT call _Quit .endif .endif ;*************************************************** .elseif eax == WM_CLOSE call _Quit ;*************************************************** .else invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .endif xor eax,eax ret WndMainProc endp _Init proc invoke SendMessage,hWinMain,WM_SETICON,ICON_SMALL,hIcon ret _Init endp ;*************************************************** _Quit proc invoke DestroyWindow,hWinMain invoke PostQuitMessage,NULL ret _Quit endp ;*************************************************** end start 窗口程序的分析 首先程序调用 _WinMain,在_WinMain 中定义了两个局部变量 @stMsg 和 @stWinMain,数据类型分别是 MSG 和 WNDCLASSEX结构,在参考手册中,可以看到WNDCLASSEX定义了一个窗口的所有参数,如使用的菜单、光标、颜色、窗口过程等,接下来的一大堆 mov 指令实际上就是在填写这个数据结构,填写完成后,最重要的两句是 mov @stWcMain.lpfnWndProc,offset WndMainProc 定义了处理消息的窗口过程, mov @stWcMain.lpszClassName,offset szClassName 定义了你要创建的类的名称,然后就是使用 RegisterClassEx 注册这个窗口类,注意,这时候窗口并没有创建,你只不过是定义好了一个子类,接下去你要用你定义的类去创建一个窗口。也就是使用 CreateWindowEx 函数去创建它。在手册中,CreateWindowEx 是这样定义的: HWND CreateWindowEx( DWORD dwExStyle, // extended window style LPCTSTR lpClassName, // pointer to registered class name LPCTSTR lpWindowName, // pointer to window name DWORD dwStyle, // window style int x, // horizontal position of window int y, // vertical position of window int nWidth, // window width int nHeight, // window height HWND hWndParent, // handle to parent or owner window HMENU hMenu, // handle to menu, or child-window identifier HINSTANCE hInstance, // handle to application instance LPVOID lpParam // pointer to window-creation data ); 其中的参数 dwExStyle 是窗口的风格,lpClassName 就是我们自己定义的类的名字。如果大家要创建一个已经定义好的类,如 RichEdit 类等等,只要把 lpClassName 指向 "RichEdit32" 字符串就行了,当然这时就不用 RegisterClass 以及编写自己的窗口过程了。执行 CreateWindowEx 后,得到一个返回值就是窗口句柄,这个值在以后是要经常用到了,所以要先保存下来。这时窗口并没有在屏幕上显示出来,而是处于隐藏状态,我们要用 ShowWindow 来显示出窗口并用UpdateWindow 来绘窗口的内容。 窗口显示出来后,程序就进入一个循环----消息循环,前面我已经说过,作用是不停地接收 Windows 消息并发送给窗口过程去处理。GetMessage 从消息队列中取出一条消息,如果取得的消息不是 WM_QUIT,那么 GetMessage 返回一个非零值,否则返回零,这时候循环结束,程序执行 ExitProcess退回操作系统。TranslateMessage 将消息进行一些键盘转换,用于处理一些快捷键,DispatchMessage 将处理后的消息发回 Windows,由Windows调用窗口进程进行处理,当窗口进程处理完返回后,程序才从 DispatchMessage 返回,从而开始下一个 GetMessage 调用。这些函的参数可以参考手册。 窗口过程的分析 窗口过程有四个参数,hWnd 是本窗口的句柄,和创建窗口时返回的值相同,uMsg 是本次调用的消息类型,wParam 和lParam是消息的参数,其含义和数值根据消息的不同而不同。在本程序中,我们处理 WM_CREATE,WM_COMMAND 和 WM_QUIT 消息,然后返回0,对不处理的消息,使用 invoke DefWindowProc,hWnd,uMsg,wParam,lParam 来处理并直接用 ret 将返回值传回 Windows。在响应 WM_CLOSE 消息时,我们用 DestroyWindow 清除窗口并用PostQuitMessage 产生一条 WM_QUIT 消息,从而使程序在 消息循环调用GetMessage 时返回0,以结束消息循环并结束程序。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行