Windows Program takes keyboard entry

Penggunaan keyboard merupakan salah satu hal penting yang digunakan sebagai masukan dan karena hanya ada satu keyboard pada masing-masing PC maka semua program Windows yang berjalan harus membagi penggunaannya. Windows bertanggung jawab untuk mengirimkan masukan keyboard ke program yang menggunakannya. Walaupun ada beberapa window pada layer, namun hanya satu diantaranya mempunyai satu masukan saja yang menggunakannya. Hal ini dapat terlihat penggunaannya dengan melihat pada title bar yang di-highlight.

Sebenarnya ada dua jenis pokok pesan keyboard, tergantung pada penggunaan keyboard dimana terlihat hanya sekumpulan key. Sehingga jika key itu ditekan maka Windows akan mengirimkan pesan WM_KEYDOWN ke window yang mempunyai masukan, yang memberitahukan bahwa key ditekan. Ketika melepaskan key tersebut, Windows mengirimkan pesan WM_KEYUP, hal ini jika menggunakan key sebagai tombol. Cara yang lain adalah melihat keyboard sebagai piranti masukan karakter, ketika menekan key ‘a’, Windows mengirimkan pesan WM_CHAR ke window masukan yang dituju dan memberitahukan bahwa pengguna mengirimkan karakter ‘a’ kepadanya. Pada kenyataannya, Windows mengirimkan pesan WM_KEYDOWN dan WM_KEYUP ke window masukan yang dituju dan pesan tersebut akan diterjemahkan ke pesan WM_CHAR oleh panggilan TranslateMessage. Prosedur window dapat memutuskan untuk memproses semua tiga pesan atau hanya pesan yang terkait dengannya. Dapat pula mengabaikan WM_KEYDOWN dan WM_KEYUP ketika pemanggilan fungsi TranslateMessage pada loop pesan yang menterjemahkan WM_KEYDOWN dan WM_KEYUP ke WM_CHAR.

.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
include \masm32\include\gdi32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\gdi32.lib

.data
ClassName db “SimpleWinClass”,0
AppName  db “Our First Window”,0
char WPARAM 20h                         ; karakter, program menerima dari keyboard

.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
    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  hInst
    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,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,SW_SHOWNORMAL
    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 hdc:HDC
    LOCAL ps:PAINTSTRUCT

    .IF uMsg==WM_DESTROY
        invoke PostQuitMessage,NULL
    .ELSEIF uMsg==WM_CHAR
        push wParam
        pop  char
        invoke InvalidateRect, hWnd,NULL,TRUE
    .ELSEIF uMsg==WM_PAINT
        invoke BeginPaint,hWnd, ADDR ps
        mov    hdc,eax
        invoke TextOut,hdc,0,0,ADDR char,1
        invoke EndPaint,hWnd, ADDR ps
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
    .ENDIF
    xor    eax,eax
    ret
WndProc endp
end start

Analisis:

char WPARAM 20h                         ; karakter, program menerima dari keyboard

Program ini merupakan variabel yang akan menyimpan karakter yang diterima dari keyboard. Karena karakter dikirimkan dalam WPARAM dari prosedur window, maka dapat didefinisikan variable sebagai tipe WPARAM untuk memudahkan. Nilai awal 20h atau ruang yang digunakan window me-refresh area klien untuk pertama kali yang menandakan tidak ada masukan karakter, sehingga untuk menampilkan ruangnya dituliskan,

    .ELSEIF uMsg==WM_CHAR
        push wParam
        pop  char
        invoke InvalidateRect, hWnd,NULL,TRUE

Hal ini menambahkan prosedur window untuk menangani pesan WM_CHAR, sehingga hanya menggunakan karakter sebagai variabel yang dinamai “char” dan kemudian memanggil InvalidateRect. invalidateRect membuat bujur sangkar tertentu dalam area klien yang membuat Windows mengirimkan pesan WM_PAINT ke prosedur window. Sintaksnya sebagai berikut,

InvalidateRect proto hWnd:HWND,\
                                 lpRect:DWORD,\
                                 bErase:DWORD

lpRect merupakan pointer ke bujur sangkar dalam area klien yang dideklarasikan invalid. Jika parameter ini null, area klien keseluruhan akan ditandai sebagai invalid.

bErase merupakan flag yang memberitahukan Windows jika perlu untuk menghapus background. Jika flag ini TRUE, maka Windows akan menghapus background bujur sangkar invalid ketika BeginPaint dipanggil.

Sehingga cara yang digunakan adalah menyimpan semua informasi yang ada terkait dengan area klien dan menampilkan pesan WM_PAINT untuk menuliskan ke area klien. Tentu saja, kode di dalam bagian WM_PAINT harus diketahui sebelumnya. Hal ini semacam cara melakukan sesuatu namun hal ini merupakan cara Windows.

Sebenarnya dapat menuliskan area klien saat pemrosesan pesan WM_CHAR dengan pemanggilan pasangan GetDC dan ReleaseDC. Sampai di sini tidak ada permasalahan, namun ketika window perlu untuk menulis ulang area klien dimana kode yang menuliskan karakter dalam bagian WM_CHAR, prosedur window tidak akan dapat untuk menulis ulang karakter dalam area klien. Sehingga baris bawah hanya meletakkan semua data dan kode yang melakukan penulisan dalam WM_PAINT. Dapat pula mengirimkan pesan WM_PAINT darimana saja dalam kode kapan pun diinginkan untuk menuliskan ulang area klien.

        invoke TextOut,hdc,0,0,ADDR char,1

 

Saat InvalidateRect dipanggil, maka dia mengirimkan pesan WM_PAINT kembali ke prosedur window sehingga kode dalam bagian WM_PAINT dipanggil. Hal ini memanggil BeginPaint sebagaimana biasanya untuk mendapatkan penanganan ke konteks piranti dan kemudian memanggil TextOut yang menuliskan karakter dalam area klien pada x=0, y=0. Ketika menjalankan program dan menekan suatu key maka akan terlihat echo karakter dalam sudut kiri atas client window. Kemudian window diminimisasi dan dimaksimisasi lagi, karakter masih ada ketika semua kode dan data yang penting untuk menulis ulang, semuanya berada dalam WM_PAINT. Eksekusi dari program di atas ditampilkan pada gambar 1 dan 2.

Gambar 1. Tampilan sebelum ada masukan karakter

Gambar 2. Tampilan sesudah ada masukan karakter

 

2 Responses

  1. saya bingung membedakan antara
    failure, fail dan error pada mikroprosesor
    tolong jelaskan

    • Failure berarti sistem tidak berjalan sebagaimanamestinya, misalkan dapat berupa proses keluaran salah langkah dalam mendefinisikan data di program sehingga keluaran tidak sesuai dengan yang diharapkan.
      Fail berarti proses komunikasi/transfer data gagal didefinisikan.
      Error berarti salah dalam meletakkan logika/algoritma/sintaks dalam tahap pengkodean.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s