3/26/10

Assembly පාඩම 9

සරල ජනේලයක් සෑදීම

අද අපි ඇසෙම්බ්ලි වලින් සරල window එකක් සෑදීමටයි යන්නේ ඇසෙම්බ්ලි වලදි මේ ක්‍රමලේකය කොටස් 2 කකින් යුක්තවනවා.
  1. message loop -(පණිවිඩ දාමය)
  2. callback function
message loop -(පණිවිඩ දාමය):
මෙය මගින් windows මගින් ලබා දෙන පණිවිඩ පිළිබඳව විමසිල්ලෙන් සිට එම පණිවිඩ අවශ්‍ය ස්ථාන වලට යොමු (dispatch)කිරීම සිදු කෙරේ
callback function:
මෙමගින් message loop මගින් dispatch කරන message ලබා ගෙන අවශ්‍යය යතුරු පුවරු ආදාන mouse event ,repainting වලට සම්බන්ධ ක්‍රියාකාර කම් පාලනය කිරීම සිදුකරයි

දැන් වැඩේ පටන් ගමු .

.386
.model flat, stdcall
option casemap :none
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

මේ අපි සාමාන්‍යයෙන් masm වලට යොදා ගන්නා දේවල්

WinMain proto :DWORD, :DWORD, :DWORD, :DWORD

මේ අපේ message loop එකේ pototype එක සී++ කට්ටියට නම් පුරුදු ඇති

.data
ClassName db "WinClass", 0
AppName db "My first Simple Window", 0
අපිට අවශ්‍ය වන variables තමා මේ

.data?
hInstance HINSTANCE ?

අපි සාදන window එක හා සම්බන්ධ handle එක ගබඩා කරන්න අවශ්‍ය variable තමා මේ පසුව අපි මේක CreateWindow function එකට පාස් කිරීම සිදු කරනවා

.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke WinMain, hInstance, NULL, NULL, 0
invoke ExitProcess, eax
start: කියලා දැක්කම තේරුම් ගන්න පුලුවන් නෙ දැන් අපේ ක්‍රමලේඛය ආරම්භ වෙලා කියලා මෙතනදි GetModuleHandle කියන function call කරලා ,EAX එකේ අගය hInstance කියන variable එක තුලට ඇතුල් කර පසුව hInstance variable එක අපගේ WinMain කියන photo type function එකතුලට පාස් කිරීම කරලා ExitProcess මගින් ක්‍රමලේඛයෙන් ඉවත් වීම සිදුවෙනවා

ඉතින් අපගේ ක්‍රමලේඛයේ වැදගත් ම කොටස WinMain function එකයි දැන් අපි ඒ code එක ගැන කතා කරමු

WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR,
CmdShow:DWORD
local wc:WNDCLASSEX
local msg:MSG
local hwnd:HWND
WinMain function තුලදි අපි මුලින්ම local variable තුනක් declare කරගන්නවා
wc වල තමා අපි හදන window class එක ගබඩා කරන්නේ window class කියන්නෙ windows හදන්න භාවිතා වෙන බ්ලූ ප්‍රින්ට් එකක් නැත්නම් template එකක් වැඩි විස්තර MSDN එකෙන් ගන්න පුලුවන්
msg වල තමා අපි message loop එකත් එක්ක සම්බන්ධ වුනු දත්ත තියාගන්නෙ ඒ වගේම hwnd එක තුල තමා හදපු වින්ඩෝ එකේ Handle එක තියා ගන්නෙ

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+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
මෙතනදී සිදුවෙලා තියෙන්නේ අපි window class එකෙන් හදා ගත්තු wc කියන හිස් object එකට (OOP වල එන object නෙමේ) දත්ත පුරවා ගැනීම හුගක් තැන් වල මම NULL යොදාගෙන තියෙන්නේ windows ලබා දෙන default අගයන්ම ලබා ගැනීමටයි මෙහි ලබා දිය හැකි අගයන් MSDN එකෙන්
බලා ගන්න පුලුවන්

මෙය තුල වෙනත් function දෙකකට (LoadIcon හා RegisterClassEx)call කිරීම සිදු කරලා තියෙනවා RegisterClassEx එකේදි wc කියන local variable එක ඒක තුලට පාස් කරනවා එමගින්CreateWindowEx call කිරීමට පෙර Class Register කිරීම සිදු කෙරෙනවා

invoke CreateWindowEx, 0, addr ClassName, addr AppName, WS_OVERLAPPEDWINDOW
or WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL,
NULL, hInst, NULL
mov hwnd, eax

මෙමගින් තමා ඇත්තම Window එක සෑදීම සිදුකරන්නේ ඒ වගේම hwnd තුලට සෑදුනු Window එකේ Handle
ඇතුල් කිරීමත් සිදුවෙනවා

.while TRUE
invoke GetMessage, addr msg, NULL, 0, 0
.break .if (!eax)
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
.endw
මේ තමා අපි කලින් කියපු message loop එක මොකක් හරි input event එකක් ආවොත් ඒ event එක message එකකට පරිවර්ථනය කරලා program එකේ message queue එකට ඇතුලත් කරනවා GetMessage මගින් message queue එකේ ඇති message එක msg variable තුල ගබඩා කරනවා ඊට පස්සෙ TranslateMessage මගින් key messages එක character messages එක් බවට පත් කරලා DispatchMessage මගින් WndProc කියන function තුලට ඇතුල් කිරීම සිදු කරනවා

mov eax, msg.wParam
ret
WinMain endp

මේ තමා WinMain ගෙ අවසානය ඊට කලින් msg.wParam අගය eax තුලට යැවීම සිදු කෙරෙනවා

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
.if uMsg == WM_DESTROY
invoke PostQuitMessage, 0
.else
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
ret
.endif
xor eax, eax
ret
WndProc endp
WndProc තමා වලදි තමා message queue තියෙන message සැකසීම සිදු කරන්නෙ මෙහිදී process කරන message එක තමා WM_DESTROY කියන එක ඒකෙන් PostQuitMessage function කෝල් කිරීම සිදුකොට ඉවත් වීම සිදුවෙනවා.එසේත් නැත්නම් DefWindowProc function මගින් default ව handle කිරීම සිදු කෙරෙනවා
ඒ වගේම ඊට අමතරව WM_CREATE,WM_PAINT හා WM_CLOSE යන නිතර භාවිතා වෙන message කිහිපයක් ඉස්සරහට මම ඒවා ගැන පැහැදිලි කරන්නම්
end start

ඒ තමා අපේ program එකේ අවසන් පේලිය

ඕක කොම්පයිල් කොරලා ලින්ක් කරගත්තට පස්සෙ අපිට මේ වගෙ ජනේලයක් බලා ගන්න පුලුවන්
ඔන්න කොහොමින් කොහොමින් හරි ඔය ගොල්ලන්ගෙ පලවෙනි ජනේලෙ හදලා ඉවරයි :D
මේ තියෙන්නේ සම්පූර්ණ code එක
.386
.model flat, stdcall
option casemap :none
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

WinMain proto :DWORD, :DWORD, :DWORD, :DWORD

.data
 ClassName db "WinClass", 0
 AppName db "My Simple Window",0
.data?
 hInstance HINSTANCE ?
.code
 start:
  invoke GetModuleHandle, NULL
  mov hInstance, eax
  invoke WinMain, hInstance, NULL, NULL, 0
  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+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
   invoke CreateWindowEx, 0, addr ClassName, addr AppName, WS_OVERLAPPEDWINDOW or WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL
   mov hwnd, eax
   
   .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
   .if uMsg == WM_DESTROY
    invoke PostQuitMessage, 0
   .else
    invoke DefWindowProc, hWnd, uMsg, wParam, lParam
    ret
   .endif
   xor eax, eax
   ret
  WndProc endp
 end start

සම්පූර්ණ code එක මෙතනින් බාගන්න පුලුවන්

0 comments:

Post a Comment