理論:
Windows 程序中,在寫圖形用戶界面時需要調用大量的標準 Windows Gui 函數(shù)。其實這對用戶和程序員來說都有好處,對于用戶,面對的是同一套標準的窗口,對這些窗口的操作都是一樣的,所以使用不同的應用程序時無須重新學習操作。對程序員來說,這些 Gui 源代碼都是經過了微軟的嚴格測試,隨時拿來就可以用的。當然至于具體地寫程序對于程序員來說還是有難度的。為了創(chuàng)建基于窗口的應用程序,必須嚴格遵守規(guī)范。作到這一點并不難,只要用模塊化或面向對象的編程方法即可。
下面我就列出在桌面顯示一個窗口的幾個步驟:
得到您應用程序的句柄(必需); 得到命令行參數(shù)(如果您想從命令行得到參數(shù),可選); 注冊窗口類(必需,除非您使用 Windows 預定義的窗口類,如 MessageBox 或 dialog box; 產生窗口(必需); 在桌面顯示窗口(必需,除非您不想立即顯示它); 刷新窗口客戶區(qū); 進入無限的獲取窗口消息的循環(huán); 如果有消息到達,由負責該窗口的窗口回調函數(shù)處理; 如果用戶關閉窗口,進行退出處理。 相對于單用戶的 DOS 下的編程來說,Windows 下的程序框架結構是相當復雜的。但是 Windows 和 DOS 在系統(tǒng)架構上是截然不同的。Windows 是一個多任務的操作系統(tǒng),故系統(tǒng)中同時有多個應用程序彼此協(xié)同運行。這就要求 Windows 程序員必須嚴格遵守編程規(guī)范,并養(yǎng)成良好的編程風格。 內容: 下面是我們簡單的窗口程序的源代碼。在進入復雜的細節(jié)前,我將提綱挈領地指出幾點要點: 您應當把程序中要用到的所有常量和結構體的聲明放到一個頭文件中,并且在源程序的開始處包含這個頭文件。這么做將會節(jié)省您大量的時間,也免得一次又一次的敲鍵盤。目前,最完善的頭文件是 hutch 寫的,您可以到 hutch 或我的網(wǎng)站下載。您也可以定義您自己的常量和結構體,但最好把它們放到獨立的頭文件中 用 includelib 指令,包含您的程序要引用的庫文件,譬如:若您的程序要調用 "MessageBox",您就應當在源文件中加入如下一行: includelib user32.lib 這條語句告訴 MASM 您的程序將要用到一些引入庫。如果您不止引用一個庫,只要簡單地加入 includelib 語句,不要擔心鏈接器如何處理這么多的庫,只要在鏈接時用鏈接開關 /LIBPATH 指明庫所在的路徑即可。 在其它地方運用頭文件中定義函數(shù)原型,常數(shù)和結構體時,要嚴格保持和頭文件中的定義一致,包括大小寫。在查詢函數(shù)定義時,這將節(jié)約您大量的時間; 在編譯,鏈接時用makefile文件,免去重復敲鍵。 .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\user32.inc includelib \masm32\lib\user32.lib ; calls to functions in user32.lib and kernel32.lib include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib WinMain proto :DWORD,:DWORD,:DWORD,:DWORD .DATA ; initialized data ClassName db "SimpleWinClass",0 ; the name of our window class AppName db "Our First Window",0 ; the name of our window .DATA? ; Uninitialized data hInstance HINSTANCE ? ; Instance handle of our program CommandLine LPSTR ? .CODE ; Here begins our code start: invoke GetModuleHandle, NULL ; get the instance handle of our program. ; Under Win32, hmodule==hinstance mov hInstance,eax mov hInstance,eax invoke GetCommandLine ; get the command line. You don't have to call this function IF ; your program doesn't process the command line. mov CommandLine,eax invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT ; call the main function invoke ExitProcess, eax ; quit our program. The exit code is returned in eax from WinMain. WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD LOCAL wc:WNDCLASSEX ; create local variables on stack LOCAL msg:MSG LOCAL hwnd:HWND mov wc.cbSize,SIZEOF WNDCLASSEX ; fill values in members of wc 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 1 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 ; register our window class invoke CreateWindowEx,NULL,\ ADDR ClassName,\ ADDR AppName,\ WS_OVERLAPPEDWINDOW,\ CW_USEDEFAULT,\ CW_USEDEFAULT,\ CW_USEDEFAULT,\ CW_USEDEFAULT,\ NULL,\ NULL,\ hInst,\ NULL mov hwnd,eax invoke ShowWindow, hwnd,CmdShow ; display our window on desktop invoke UpdateWindow, hwnd ; refresh the client area .WHILE TRUE ; Enter message loop invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ; return exit code in eax ret WinMain endp WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY ; if the user closes our window invoke PostQuitMessage,NULL ; quit our application .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ; Default message processing ret .ENDIF xor eax,eax ret WndProc endp end start 分析: 看到一個簡單的 Windows 程序有這么多行,您是不是有點想撤? 但是您必須要知道的是上面的大多數(shù)代碼都是模板而已,模板的意思即是指這些代碼對差不多所有標準 Windows 程序來說都是相同的。在寫 Windows 程序時您可以把這些代碼拷來拷去,當然把這些重復的代碼寫到一個庫中也挺好。其實真正要寫的代碼集中在 WinMain 中。這和一些 C 編譯器一樣,無須要關心其它雜務,集中精力于 WinMain 函數(shù)。唯一不同的是 C 編譯器要求您的源代碼有必須有一個函數(shù)叫 WinMain。否則 C 無法知道將哪個函數(shù)和有關的前后代碼鏈接。相對C,匯編語言提供了較大的靈活性,它不強行要求一個叫 WinMain 的函數(shù)。 下面我們開始分析,您可得做好思想準備,這可不是一件太輕松的活。 .386 .model flat,stdcall option casemap:none WinMain proto :DWORD,:DWORD,:DWORD,:DWORD include \masm32\include\windows.inc include \masm32\include\user32.inc include \masm32\include\kernel32.inc includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib 您可以把前三行看成是"必須"的. .386告訴MASN我們要用80386指令集。 . model flat,stdcall告訴MASM 我們用的內存尋址模式,此處也可以加入stdcall告訴MASM我們所用的參數(shù)傳遞約定。 接下來是函數(shù) WinMain 的原型申明,因為我們稍后要用到該函數(shù),故必須先聲明。我們必須包含 window.inc 文件,因為其中包含大量要用到的常量和結構的定義,該文件是一個文本文件,您可以用任何文本編輯器打開它, window.inc還沒有包含所有的常量和結構定義,不過 hutch 和我一直在不斷加入新的內容。 |
免責聲明:本站部分文章和圖片均來自用戶投稿和網(wǎng)絡收集,旨在傳播知識,文章和圖片版權歸原作者及原出處所有,僅供學習與參考,請勿用于商業(yè)用途,如果損害了您的權利,請聯(lián)系我們及時修正或刪除。謝謝!
始終以前瞻性的眼光聚焦站長、創(chuàng)業(yè)、互聯(lián)網(wǎng)等領域,為您提供最新最全的互聯(lián)網(wǎng)資訊,幫助站長轉型升級,為互聯(lián)網(wǎng)創(chuàng)業(yè)者提供更加優(yōu)質的創(chuàng)業(yè)信息和品牌營銷服務,與站長一起進步!讓互聯(lián)網(wǎng)創(chuàng)業(yè)者不再孤獨!
掃一掃,關注站長網(wǎng)微信