ข้อมูลจาก Iczelion
บทนี้เราจะมาศึกษากันถึงการรับข้อมูลจากคีย์บอร์ด
ในระบบปฏิบัติการวินโดวส์สามารถจะรันโปรแกรมหลายๆ โปรแกรมได้พร้อม ๆ กัน แต่ว่าเครื่องคอมพิวเตอร์ของเรานั้นจะมีคีย์บอร์ดแค่อันเดียว ดังนั้นระบบจะเป็นตัวจัดการส่งข้อมูลที่เราพิมพ์ให้กับวินโดว์ที่กำลังได้รับโฟกัสอยู่ ซึ่งก็จะมีเพียงวินโดว์เดียวที่จะได้รับข้อมูลนี้ในขณะนั้น
จริงๆ แล้วข้อมูลของคีย์บอร์ดแบ่งออกได้เป็น 2 ประเภทหลักๆ ขึ้นอยู่กับว่าคุณจะมองคีย์บอร์ดอย่างไร ถ้าคุณมองคีย์บอร์ดเป็นที่รวบรวมของคีย์ต่างๆ เมื่อคุณกดคีย์บอร์ด วินโดวส์จะส่งเมสเสจ WM_KEYDOWN ให้กับวินโดว์ที่กำลังรับโฟกัสอยู่เพื่อบอกว่ามีการกดคีย์บอร์ด เมื่อคุณปล่อยนิ้วจากคีย์บอร์ด วินโดวส์ก็จะส่งเมสเสจ WM_KEYUP ให้กับวินโดว์นั้น แต่ถ้าคุณมองคีย์บอร์ดเป็นอุปกรณ์สำหรับป้อนตัวอักษร เมื่อคุณกดคีย์บอร์ดวินโดวส์จะส่งเมสเสจ WM_CHAR ไปให้กับวินโดว์ที่กำลังรับโฟกัสอยู่เพื่อบอกว่าผู้ใช้ได้ส่งตัวอักษรไปให้ แต่จริงๆ แล้ววินโดวส์ส่งเมสเสจ WM_KEYDOWN และ WM_KEYUP ไปให้ จากนั้นเมสเสจทั้งสองนี้ก็จะถูกแปลงเป็นเมสเสจWM_CHAR โดยการเรียกใช้ฟังก์ชั่น TranslateMessage โพรซิเยอร์ของวินโดว์จะเป็นตัวตัดสินใจว่าจะใช้งานเมสเสจทั้งสามนี้หรือเลือกเอาเฉพาะเมสเสจที่มันต้องการ แต่ส่วนใหญ่แล้วคุณไม่ต้องส่นใจเมสเสจ WM_KEYDOWN และ WM_KEYUP ก็ได้ เพราะว่าฟังก์ชั่น TranslateMessage ในเมสเสจลูปจะแปลงเมสเสจทั้งสองนี้ให้เป็นเมสเสจ WM_CHAR อยู่แล้ว ดังนั้นบทนี้จึงเน้นที่ WM_CHAR
|
| char WPARAM 20h ; ตัวอักษรที่วินโดว์รับจากคีย์บอร์ด |
char เป็นตัวแปรสำหรับเก็บตัวอักษรที่รับมาจากคีย์บอร์ด เพราะว่าตัวอักษรจะถูกส่งมาในรูปแบบ WPARAM ในโพรซิเยอร์ WndProc ของวินโดว์ ดังนั้นเพื่อความสะดวกจึงสร้างให้มีรูปแบบเป็น WPARAM ส่วนค่าเริ่มต้น 20h นั้น เป็นค่าของรหัสช่องว่าง สำหรับให้พื้นที่แสดงผลแสดงช่องว่างในตอนที่วินโดว์เริ่มรันครั้งแรก
.ELSEIF uMsg==WM_CHAR push wParam pop char invoke InvalidateRect, hWnd,NULL,TRUE |
มีฟังก์ชั่นเพิ่มเติมที่วินโดว์ใช้จัดการกับเมสเสจ WM_CHAR มันจะเก็บตัวอักษรในตัวแปร char แล้วจึงเรียกฟังก์ชั่น InvalidateRect ฟังก์ชั่นนี้จะทำให้พื้นที่ทำงานที่กำหนดมีสถานะใช้การไม่ได้ซึ่งจะบังคับให้วินโดวส์ส่งเมสเสจ WM_PAINT ไปยังโพรซิเยอร์ของวินโดว์ รูปแบบของฟังก์ชั่นนี้คือ
InvalidateRect proto hWnd:HWND,\ lpRect:DWORD,\ bErase:DWORD |
lpRect เป็นพอยเตอร์ที่ชี้ยังยังพื้นที่สี่เหลี่ยนในพื้นที่ทำงานที่เราต้องการกำหนดให้มีสถานะใช้งานไม่ได้ ถ้ามีค่าเป็น null พื้นที่นั้นจะหมายถึงพื้นที่ทำงานทั้งหมด
bErase เป็นแฟล็กที่บอกวินโดวส์ว่าจะลบพื้นที่ด้านหลังด้วยหรือไม่ ถ้ามีค่าเป็น TRUE วินโดวส์จะลบพื้นที่ด้านหลังของพื้นที่ที่ถูกกำหนดเมื่อฟังก์ชั่น BeginPaint ถูกเรียก
ดังนั้นเราจึงวางแผนโดยการเก็บข้อมูลที่จำเป็นในการวาดลงในพื้นที่ทำงานแล้วจึงส้รางเมสเสจ WM_PAINT เพื่อให้ทำการวาดพื้นที่ทำงานใหม่ แน่นอนว่าเราต้องทราบโค้ดในส่วนของ WM_PAINT ก่อนว่าจะทำอะไร
จริง ๆ แล้วเราสามารถวาดลงในพื้นที่ทำงานระหว่างที่จัดการเมสเสจ WM_CHAR โดยการใช้คู่ของฟังก์ชั่น GetDC และ ReleaseDC ได้ แต่จะไม่สามารถวาดตัวอักษรของเราในพื้นที่ทำงานใหม่ได้ ที่ให้ทำงานในส่วนของ WM_PAINT เพราะว่าเราสามารถสั่งให้วินโดวส์ทำการวาดพื้นที่ทำงานใหม่โดยการส่งเมสเสจ WM_PAINT ณ สถานที่และเวลาใดก็ได้ที่เราต้องการ
invoke TextOut,hdc,0,0,ADDR char,1 |
เมื่อฟังก์ชั่น InvalidateRect ถูกเรียก มันจะส่งเมสเสจ WM_PAINT กลับไปยังโพรซิเยอร์ของวินโดว์ ดังนั้นโค้ดในส่วนของ WM_PAINT จึงถูกเรียกให้ทำงาน ฟังก์ชั่น BeginPaint จึงสร้างแฮนเดิ้ลของดีไวซ์คอนเท็กซ์แล้วจึงเรียกฟังก์ชั่น TextOut เพื่อวาดตัวอักษรของเราในพื้นที่ทำงานที่ x=0และ y=0 เมื่อคุณรันโปรแกรมและกดคีย์ใดๆ จะเห็นตัวอักษรปรากฏขึ้นที่มุมบนซ้ายของพื้นที่ทำงาน เมื่อวินโดว์ถูกย่อขนาดแล้วขยายขึ้นใหม่ ตัวอักษรก็จะยังคงอยู่ที่เดิมเพราะว่าโค้ดและข้อมูลที่จำเป็นทั้งหมดในการวาดใหม่รวมอยู่ในส่วนของ WM_PAINT