สรุป
แอปพลิเคชันที่ใช้ Windows มักแสดงกล่องโต้ตอบรายการข้อมูลเพื่อร้องขอข้อมูลจากผู้ใช้ กล่องโต้ตอบเหล่านี้อาจประกอบด้วยตัวควบคุมการแก้ไขและปุ่มคำสั่งสองปุ่ม (push) ที่มีป้ายชื่อตกลงและยกเลิก ตัวอย่างของกล่องโต้ตอบรายการข้อมูลเป็นรายการที่ร้องขอข้อมูลส่วนบุคคลเช่นหมายเลขประกันสังคมที่อยู่รหัสประจำตัว (ID) วันที่/เวลาและอื่นๆจากผู้ใช้ แต่ละรายการเหล่านี้จะถูกใส่ลงในตัวควบคุมการแก้ไข ตามค่าเริ่มต้นแป้น TAB จะถูกใช้ในกล่องโต้ตอบเพื่อเปลี่ยนโฟกัสไปมาระหว่างตัวควบคุมการแก้ไข อย่างไรก็ตามคุณสามารถใช้คีย์ ENTER (RETURN) เมื่อต้องการย้ายไปมาระหว่างตัวควบคุมการแก้ไข (ตัวอย่างเช่นหลังจากที่ผู้ใช้ใส่ข้อมูลของข้อมูลแล้วการกด ENTER จะย้ายโฟกัสไปยังเขตข้อมูลถัดไป) มีสองสามวิธีในการเปิดใช้งานการใช้แป้น ENTER เพื่อย้ายไปมาระหว่างตัวควบคุมการแก้ไข วิธีหนึ่งคือการใช้ WM_COMMAND และข้อความแจ้งเตือนที่มาพร้อมกับข้อความในกล่องโต้ตอบเพื่อแก้ไขตัวควบคุมและปุ่มต่างๆ อีกวิธีหนึ่งที่เกี่ยวข้องกับ subclassing ตัวควบคุมการแก้ไข ที่สามที่เกี่ยวข้องกับการใช้แอป Studio และตัวช่วยสร้างชั้นเรียนและการสร้างฟังก์ชันสมาชิกของกล่องโต้ตอบใหม่
ข้อมูลเพิ่มเติม
วิธีที่ 1: (WM_COMMAND)
วิธีนี้จะยึดตามลักษณะการทำงานต่อไปนี้ของกล่องโต้ตอบ (ตัวจัดการกล่องโต้ตอบ) และการจัดการโฟกัสใน Windows ถ้ากล่องโต้ตอบหรือตัวควบคุมตัวใดตัวหนึ่งในปัจจุบันมีโฟกัสการป้อนข้อมูลแล้วให้กดแป้น ENTER ทำให้ Windows ส่งข้อความ WM_COMMAND ด้วยพารามิเตอร์ idItem (wParam) ที่ตั้งค่าเป็น ID ของปุ่มคำสั่งเริ่มต้น ถ้ากล่องโต้ตอบไม่มีปุ่มคำสั่งเริ่มต้นแล้วพารามิเตอร์ idItem จะถูกตั้งค่าเป็น IDOK ตามค่าเริ่มต้น เมื่อแอปพลิเคชันได้รับข้อความ WM_COMMAND ที่มี idItem ตั้งค่าเป็น ID ของปุ่มคำสั่งเริ่มต้นโฟกัสจะยังคงอยู่กับตัวควบคุมที่มีโฟกัสก่อนที่จะกดแป้น ENTER การโทร GetFocus () ณจุดนี้จะส่งกลับจุดจับของตัวควบคุมที่มีโฟกัสก่อนที่จะกดแป้น ENTER แอปพลิเคชันสามารถตรวจสอบจุดจับควบคุมนี้และกำหนดว่าจะเป็นสมาชิกของตัวควบคุมการแก้ไขในกล่องโต้ตอบหรือไม่ ถ้ามีแล้วผู้ใช้กำลังใส่ข้อมูลลงในตัวควบคุมการแก้ไขหนึ่งและหลังจากการทำเช่นนั้นให้กด ENTER ณจุดนี้แอปพลิเคชันสามารถส่งข้อความ WM_NEXTDLGCTL ไปยังกล่องโต้ตอบเพื่อย้ายโฟกัสไปยังตัวควบคุมถัดไป อย่างไรก็ตามถ้าโฟกัสมีปุ่มคำสั่งหนึ่งปุ่ม (ยกเลิกหรือตกลง) แล้ว GetFocus () จะส่งกลับจุดจับตัวควบคุมปุ่มที่จุดหนึ่งสามารถยกเลิกกล่องโต้ตอบได้ โค้ดเทียมสำหรับตรรกะนี้มีลักษณะดังต่อไปนี้ในกระบวนงานของกล่องโต้ตอบของแอปพลิเคชัน:
case WM_COMMAND: if(wParam=IDOFDEFBUTTON || IDOK) { // User has hit the ENTER key. hwndTest = GetFocus() ; retVal = TesthWnd(hWndTest) ; //Where retVal is a boolean variable that indicates whether //the hwndTest is the handle of one of the edit controls. if(hwndTest) { //Focus is with an edit control, so do not close the dialog. //Move focus to the next control in the dialog. PostMessage(hDlg, WM_NEXTDLGCTL, 0, 0L) ; return TRUE ; } else { //Focus is with the default button, so close the dialog. EndDialog(hDlg, TRUE) ; return FALSE ; } } break ;
วิธีที่2
วิธีนี้เกี่ยวข้องกับ subclassing/superclassing ตัวควบคุมการแก้ไขในกล่องโต้ตอบ เมื่อตัวควบคุมการแก้ไขคือ subclassed หรือ superclassed การป้อนข้อมูลบนคีย์บอร์ดทั้งหมดจะถูกส่งไปยังกระบวนงานระดับชั้นย่อย/ซุปของตัวควบคุมการแก้ไขที่มีโฟกัสการป้อนข้อมูลไม่ว่าในขณะนี้กล่องโต้ตอบจะมีปุ่มคำสั่งเริ่มต้นหรือไม่ แอปพลิเคชันสามารถ trap ข้อความแป้นลง (หรืออักขระ) ให้มองหาคีย์ ENTER และทำการประมวลผลตามลำดับ ต่อไปนี้คือขั้นตอนของระดับชั้นย่อยตัวอย่างที่ค้นหาคีย์ ENTER:
//*------------------------------------------------------------------- //| Title: //| SubClassProc //| //| Parameters: //| hWnd - Handle to the message's destination window //| wMessage - Message number of the current message //| wParam - Additional info associated with the message //| lParam - Additional info associated with the message //| //| Purpose: //| This is the window procedure used to subclass the edit control. //*--------------------------------------------------------------------- long FAR PASCAL SubProc(HWND hWnd, WORD wMessage,WORD wParam,LONG lParam) { switch (wMessage) { case WM_GETDLGCODE: return (DLGC_WANTALLKEYS | CallWindowProc(lpOldProc, hWnd, wMessage, wParam, lParam)); case WM_CHAR: //Process this message to avoid message beeps. if ((wParam == VK_RETURN) || (wParam == VK_TAB)) return 0; else return (CallWindowProc(lpOldProc, hWnd, wMessage, wParam, lParam)); case WM_KEYDOWN: if ((wParam == VK_RETURN) || (wParam == VK_TAB)) { PostMessage (ghDlg, WM_NEXTDLGCTL, 0, 0L); return FALSE; } return (CallWindowProc(lpOldProc, hWnd, wMessage, wParam, lParam)); break ; default: break; } /* end switch */
วิธีที่ 3
วิธีนี้เกี่ยวข้องกับการใช้แอป Studio และ ClassWizard และการสร้างฟังก์ชันสมาชิกของกล่องโต้ตอบใหม่ วิธีนี้จะอนุญาตให้ผู้ใช้กดแป้น ENTER และมีโฟกัสล่วงหน้าไปยังตัวควบคุมการแก้ไขถัดไป ถ้าโฟกัสอยู่ในตัวควบคุมการแก้ไขล่าสุดในกล่องโต้ตอบโฟกัสจะเลื่อนไปที่ตัวควบคุมการแก้ไขแรก ก่อนอื่นให้ใช้แอป Studio เพื่อเปลี่ยน ID ของปุ่มตกลงของกล่องโต้ตอบ ลักษณะการทำงานเริ่มต้นของแอป Studio คือการให้ปุ่มตกลง ID IDOK รหัสของปุ่มตกลงควรถูกเปลี่ยนเป็นค่าอื่นเช่น IDC_OK นอกจากนี้ให้เปลี่ยนคุณสมบัติของปุ่มตกลงเพื่อไม่ให้เป็นค่าเริ่มต้นฟังก์ก ถัดไปให้ใช้ ClassWizard เพื่อสร้าง funciton สมาชิกของกล่องโต้ตอบใหม่ ตั้งชื่อฟังก์ชันสมาชิกใหม่สิ่งที่ชอบ OnClickedOK ฟังก์ชันนี้ควรจะเชื่อมโยงกับข้อความ BN_CLICKED จากตัวควบคุม IDC_OK เมื่อทำเสร็จแล้วให้เขียนเนื้อความของฟังก์ชัน OnClickedOK คุณควรใส่โค้ดที่คุณมักจะใส่ในฟังก์ชัน OnOK ลงในฟังก์ชัน OnClickedOK ใหม่รวมถึงฟังก์ชัน OnOK ของชั้นเรียน เพิ่มต้นแบบต่อไปนี้ไปยังไฟล์หัวกระดาษสำหรับกล่องโต้ตอบ:
protected: virtual void OnOK();
เพิ่มฟังก์ชัน OnOK ไปยังกล่องโต้ตอบและโค้ดจะแสดงตามที่แสดงด้านล่าง:
void CMyDialog::OnOK() { CWnd* pwndCtrl = GetFocus(); CWnd* pwndCtrlNext = pwndCtrl; int ctrl_ID = pwndCtrl->GetDlgCtrlID(); switch (ctrl_ID) { case IDC_EDIT1: pwndCtrlNext = GetDlgItem(IDC_EDIT2); break; case IDC_EDIT2: pwndCtrlNext = GetDlgItem(IDC_EDIT3); break; case IDC_EDIT3: pwndCtrlNext = GetDlgItem(IDC_EDIT4); break; case IDC_EDIT4: pwndCtrlNext = GetDlgItem(IDC_EDIT1); break; case IDOK: CDialog::OnOK(); break; default: break; } pwndCtrlNext->SetFocus(); }