본문 바로가기
공부,일/어셈블리

튜토리얼 3 simple window

by fromnothing1 2021. 8. 16.
.386
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib            ; user32.lib 과 kernel32.lib 안에 있는 함수를 사용하기 위해서
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib

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

.DATA   ; 초기화한 데이터 
ClassName db "SimpleWinClass",0   ; window class 이름
AppName db "Our First Window",0   ;  윈도우(창) 이름


.DATA?   ; 초기화 되지 않은 데이터
hInstance HINSTANCE ?   ; 프로그램의 인스턴스 핸들
CommandLine LPSTR ?


.CODE   ; 여기서부터 코드가 시작
start:
invoke GetModuleHandle, NULL   ; 프로그램의 인스턴스 핸들을 구함

mov hInstance,eax
invoke GetCommandLine   ; 커맨드 라인을 가져옴. 프로그램에서 커맨드 라인이
                                   ; 필요하지 않는다면, 이 함수를 호출 할 필요가 없음
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT   ; main 함수 호출
invoke ExitProcess, eax   ; 프로그램 종료. exit code 는 WinMain 가  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   ; 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                       ; 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   ; 화면에 window 를 출력
    invoke UpdateWindow, hwnd   ; client 영역을 새로그림


    .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   ; 종료코드를 eax 에 채워서 리턴
    ret
WinMain endp


WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    .IF uMsg==WM_DESTROY   ; 사용자가 창을 닫을 경우
        invoke PostQuitMessage,NULL   ; 프로그램을 종료
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam   ; 기본 메세지들 처리
        ret
    .ENDIF
    xor eax,eax
    ret
WndProc endp

end start

- 윈도우 만드는 방법 

 

1. 프로그램의 인스턴스 핸들을 가져옴(필수사항) 
2. 커맨드 라인을 가져옴(프로그램에서 커맨드 라인이 필요하지 않다면 필수사항 아님) 
3. 윈도우 클래스(window class) 등록함(MessageBox 나 dialogbox 처럼 미리 정의되어 있는 윈도우 타입을 사용할 것이 아니라면 필수사항) 
4. 윈도우 만듦(필수사항) 
5. 바탕화면 위에 창 보이기(창이 즉시 보여지는지길 원한다면 필수사항) 
6. 창의 클라이언트 영역을 새로고침 
7. Windows의 메세지를 체크하기 위한 무한루프로 들어감 
8. 메세지가 도착하면, 그 창을 책임지고 있는 특정 함수가 처리함 
9. 사용자가 창을 닫으면 프로그램은 종료됨

출처: https://crystalcube.co.kr/17?category=269249 [유리상자 속 이야기]

'공부,일 > 어셈블리' 카테고리의 다른 글

ch3 data & operand  (0) 2021.08.16
listing 파일 만들기  (0) 2021.08.16
튜토리얼 2(메세지 박스 만들기)  (0) 2021.08.15
튜토리얼 1  (0) 2021.08.13
__cdecl vs __stdcall  (0) 2021.08.13

댓글