Visual C++
การเขียนโปรแกรมโดยใช้ MFC (Microsoft foundation class)

MFC คืออะไร?
กล่าวอย่างง่าย ๆ MFC ก็คือกลุ่มของ คลาส (class) ในภาษา C++ ที่ถูกออกแบบมา เพื่อช่วย ให้การเขียน โปรแกรมใน วินโดวส์ ง่ายและ รวดเร็วขึ้นนั่นเอง โดย MFC จะประกอบไปด้วย คลาสที่มี การสืบทอด (hierarchy) กันมา เป็นชั้น ๆ รวมแล้วประมาณ 200 คลาส ซึ่งครอบคลุม การทำงานพื้นฐาน ของการเขียนโปรแกรม ในวินโดวส์ ได้เกือบทั้งหมด
และเนื่องจาก MFC เป็นกลุ่มของคลาส ที่เขียนขึ้น โดยใช้ภาษา C++ ดังนั้น คุณจะต้องมี ความรู้ในภาษา C++ ดีพอสมควร เพื่อที่จะสามารถ ใช้งาน MFC ได้อย่างมีประสิทธิภาพ แต่ถ้าคุณเป็นมือใหม่ ก็ไม่เป็นไรค่ะ ก็เรียนรู้ไปพร้อม ๆ กับดิฉันก็ได้

โครงสร้างพื้นฐานของโปรแกรมที่เขียนด้วย MFC
โปรแกรม ที่เขียนขึ้นโดยใช้ MFC จะประกอบไปด้วย คลาสอย่างน้อย 2 คลาส คือ
ซึ่งในบทความนี้ Window Class ของเรา จะสืบทอดมาจาก คลาสที่ชื่อ CFrameWnd ส่วน Application Class จะสืบทอดมาจาก คลาส CWinApp

ขั้นตอนของการเขียนโปรแกรมโดยใช้ MFC
  1. สืบทอด (derive) คลาส ของหน้าต่างโปรแกรม ของเรา มาจากคลาส CFrameWnd
  2. สืบทอดคลาส ของโปรแกรม (application) ของเรา มาจาก คลาส CWinApp
  3. กำหนด message map (จะได้กล่าวถึงต่อไปในตอนหลัง)
  4. เขียน ชุดคำสั่ง ที่ใช้ในฟังก์ชั่น InitInstance ของคลาส CWinApp ขึ้นมา
  5. สร้างวัตถุ (instance) ของคลาส application ของเราขึ้นมา

คราวนี้เรามาลองเขียนโปรแกรม โดยใช้ MFC กันดูนะคะ อันดับแรกก็ทำการสร้าง โปรเจคขึ้นมาใหม่ โดยทำ ตามขั้นตอนที่ ได้กล่าวไปแล้ว ในบทที่ 1 ก็จะได้หน้าจอหลัก ของ Visual C++ compiler ดังแสดงในรูป

ต่อไปนี้แหละค่ะ เป็นขั้นตอนสำคัญ เพราะตอนนี้ เราจะต้อง set ชนิดของโปรเจ็คให้ใช้ MFC ด้วย โดยให้ ไปคลิ๊กที่เมนู Project เลือกหัวข้อ Setting จะได้ไดอะล็อก ออกมาดังแสดงในรูป

จะเห็นว่าในหัวข้อ Microsoft Foundation Class นั้น จะมีตัวเลือก 3 ตัวเลือกคือ

ในที่นี้เราจะเลือกเอาตัวเลือก Use MFC in a Shared DLL เพื่อให้ไฟล์โปรแกรมที่ได้ มีขนาดไม่ใหญ่ มากนัก แต่ถ้าคุณจะนำ โปรแกรมที่เขียนขึ้น ไปใช้กับเครื่องอื่น ที่ไม่แน่ใจว่ามีไฟล์ MFC42.DLL อยู่ด้วย ก็ให้เลือก ตัวเลือกเป็น Use MFC in a Static Library ก็ได้ค่ะ
จากนั้นก็ใช้คลิ๊กเลือกเมนู File -> New ก็จะได้ไดอะล๊อกดังแสดงในรูปด้านล่าง

แล้วทำตามขั้นตอนคือ

  1. คลิ๊กเลือกแทป Files เพื่อเป็นการสร้างไฟล์ใหม่
  2. คลิ๊กเลือกชนิดของไฟล์ เป็น C++ Source file
  3. ป้อนชื่อไฟล์ ที่เราจะสร้างตามต้องการ ในที่นี้ให้ชื่อ mymfc.cpp
  4. คลิ๊ก OK
ก็จะกลับเข้าสู่ หน้าจอเดิม ดังในรูป

จากนั้นก็ให้เขียนโปรแกรม ตามตัวอย่างข้างล่างนี้ ลงในหน้าต่าง 1

#include <afxwin.h> /* สืบทอดคลาสหน้าต่างหลัก จาก คลาส CFramWnd */ class CMainWin: public CFrameWnd { public: CMainWin(); /* ประกาศ function contructor */ DECLARE_MESSAGE_MAP() /* ประกาศ message map ของหน้าต่างหลักนี้ */ }; CMainWin::CMainWin() { Create(NULL, "Simple MFC program"); } /* สืบทอดคลาสที่ใช้ควบคุมโปรแกรม จากคลาส CWinApp */ class CApp : public CWinApp { public: BOOL InitInstance(); /* ฟังก์ชั่นในการ สร้างวัตถุเป้าหมาย ของคลาส */ }; /* รายละเอียดของ ฟังก์ชั่น */ BOOL CApp::InitInstance() { m_pMainWnd = new CMainWin; m_pMainWnd -> ShowWindow(m_nCmdShow); m_pMainWnd -> UpdateWindow(); return TRUE; } /* รายละเอียดของ message map */ BEGIN_MESSAGE_MAP(CMainWin,CFrameWnd) END_MESSAGE_MAP() CApp myapp; /* สร้างวัตถุเป้าหมาย ของคลาสของโปรแกรมของเรา */

จากนั้นก็ทำการ Build Source Code ของเรา ให้เป็นโปรแกรม ที่ทำงานได้ โดยเลือก เมนู Build -> Build ชื่อโปรแกรม หรือกด F7 หรือเลือกใช้ Tool bar ก็ได้ เหมือนในบทที่ 3 นะคะ
จากนั้นก็ใช้คำสั่ง Build -> Execute ชื่อไฟล์เรา หรือใช้ Tool bar เหมือนในบทที่ 3 ก็ได้ ก็จะได้ หน้าต่างโปรแกรมของเรา ดังแสดงในรูปค่ะ
จะเห็นว่า การเขียนโปรแกรม แบบเดียวกัน โดยใช้ MFC มาช่วย จะทำให้เราเขียน โค้ดคำสั่งของโปรแกรม น้อยลงมาก

คราวนี้เรามาดูรายละเอียด ของโปรแกรมนี้ กันนะคะ

#include <afxwin.h>

โปรแกรมที่เขียนขึ้น โดยใช้ MFC จะต้องมีการ include ไฟล์ afxwin.h ไว้ด้วยเสมอ ซึ่งภายในไฟล์นี้ ได้มีการกำหนดค่า ต่าง ๆ ที่จะใช้กับโปรแกรม ที่เขียนด้วย MFC ไว้เรียบร้อยแล้ว

class CMainWin: public CFrameWnd { public: CMainWin(); /* ประกาศ function contructor */ DECLARE_MESSAGE_MAP() /* ประกาศ message map ของหน้าต่างหลักนี้ */ };

เป็นการประกาศคลาสใหม่ ที่ชื่อ CMainWin โดยสืบทอดมาจาก คลาส CFrameWnd ซึ่งเป็น คลาสที่ทำหน้าที่ กำหนด ลักษณะของหน้าต่าง โปรแกรมของเรา โดยภายในคลาสนี้ ได้มีการประกาศ function constructor ซึ่งเป็นฟังก์ชั่น ที่จะถูกเรียกใช้งานทันที ที่มีการสร้างวัตถุเป้าหมาย ของคลาสนี้ขึ้นมา และยังมีการประกาศ มาโคร ที่ใช้ในกระบวนการ map message เอาไว้ด้วย ซึ่งรายละเอียดของ การ map message นี้จะได้ กล่าวถึงในบทต่อไป

class CApp : public CWinApp { public: BOOL InitInstance(); /* ฟังก์ชั่นในการ สร้างวัตถุเป้าหมาย ของคลาส */ };

เป็นการประกาศคลาสใหม่ ที่ชื่อ CApp ซึ่งสืบทอด มาจากคลาส CWinApp คลาสนี้ เป็นตัวกำหนดลักษณะ ของ โปรแกรมของเรา โดย ภายในคลาสนี้ มีการประกาศ ฟังก์ชั่นสมาชิกชื่อ InitInstance() อยู่ในคลาสด้วย

ชั้นตอนการ ทำงานของ โปรแกรมเรา จะเริ่มขึ้นจาก บรรทัดต่อไปนี้ค่ะ

CApp myapp;

ซึ่งเป็นคำสั่ง ให้มีการสร้างวัตถุเป้าหมาย (object) ของคลาส CApp ขึ้นมา เมื่อมีการสร้างวัตถุเป้าหมาย ก็จะ ทำให้ มีการเรียกฟังก์ชั่น InitInstance(); ซึ่งเป็นฟังก์ชั่นสมาชิกของ คลาสนี้ ขึ้นมาทำงานโดยอัตโนมัติ

BOOL CApp::InitInstance() { m_pMainWnd = new CMainWin; m_pMainWnd -> ShowWindow(m_nCmdShow); m_pMainWnd -> UpdateWindow(); return TRUE; }

เมื่อฟังก์ชั่น InitInstance() ถูกเรียกให้ทำงาน ก็จะมีการทำงานตามขั้นตอน ดังต่อไปนี้ค่ะ
1.1 กระทำคำสั่ง m_pMainWnd = new CMainWin;
เป็นคำสั่งให้ มีการสร้าง วัตถุเป้าหมาย ของคลาส CMainWin ขึ้นมา โดยให้ตัวแปร m_pMainWnd ซึ่งเป็นตัวแปร สมาชิกของคลาส CApp เก็บค่าตำแหน่งที่ชี้ไปยังหน่วยความจำ ที่เก็บวัตถุเป้าหมายนี้ไว้
เมื่อมีการสร้าง วัตถุเป้าหมาย ของคลาส CMainWin ก็จะมีการเรียก Function Constructor ขึ้นมาทำงาน ซึ่งภายใน function constructor มีฟังก์ชั่นอยู่ฟังก์ชั่นเดียว ก็คือ

CMainWin::CMainWin() { Create(NULL, "Simple MFC program"); }

คำสั่ง Create(NULL, "Simple MFC prgram"); ก็จะทำให้ มีการสร้าง หน้าต่างหลัก ของโปรแกรม ของเราขึ้นมา แต่ขั้นตอนนี้ ยังไม่มี รูปหน้าต่าง ของโปรแกรมเรา ขึ้นมาบนจอภาพนะคะ
1.2 คำสั่ง m_pMainWnd -> ShowWindow(m_nCmdShow); นี่แหละค่ะ ที่จะทำให้เกิดหน้าต่าง ของโปรแกรมเรา ขึ้นมาบนจอภาพ โดยตัวแปร m_nCmdShow จะเป็นตัวกำหนด ว่าจะให้แสดง หน้าต่างโปรแกรม ออกมาแบบใด
1.3 คำสั่ง m_pMainWnd -> UpdateWindow(); เป็นตัวส่ง message ไปให้ระบบปฏิบัติการ วินโดวส์ รู้ว่า ควรจะต้อง มีการเขียนหน้าจอภาพ ขึ้นใหม่
เมื่อมีการ วาดหน้าต่าง ของโปรแกรมเรา ออกบนจอภาพเรียบร้อยแล้ว ก็จะมีการกระบวนการ map message

BEGIN_MESSAGE_MAP(CMainWin,CFrameWnd) END_MESSAGE_MAP()

โดยขึ้นต้นด้วย คำสั่งมาโคร BEGIN_MESSAGE_MAP(ชื่อคลาสที่มีการ map messagge นี้, ชื่อคลาสแม่) จะสังเกตว่า ไม่มีเครื่องหมาย ';' ต่อท้ายคำสั่งนี้
และ จะปิดท้ายด้วยคำสั่งมาโคร END_MESSAGE_MAP() ซึ่งกระบวนการ map message จะได้กล่าวถึง ในบทต่อไป ค่ะ

สุดท้ายนี้ คุณ ๆ ผู้อ่าน บทความนี้ หลาย ๆ ท่าน อาจจะงง ๆ อยู่ ก็ขอให้ ลองไปหาหนังสือ เกี่ยวกับ การเขียนโปรแกรม ภาษา C++ มาอ่านดูนะคะ อย่างเช่น หนังสือ "การเขียน โปรแกรมแบบ โอโอพี ด้วยบอร์แลนด์ และเทอร์โบซี" ที่เรียบเรียง โดยคุณ ราบิน เดอร์ ศรีกิจจาภรณ์ ก็จะช่วยทำให้ คุณ ๆ มีความเข้าใจ เกี่ยวกับ คลาส (class), virtual function, และ overload function ได้ดียิ่งขึ้นค่ะ ส่วนฟังก์ชั่น คำสั่งต่าง ๆ ที่พบใน บทความนี้ ก็ให้หารายละเอียด เพิ่มเติมได้จาก ในแผ่นซีดี MSDN ที่ให้มา พร้อมกับแผ่น โปรแกรม Visual C++ 6 compiler นะคะ

ขอให้มีความสุข กับการเขียนโปรแกรมนะคะ พบกันใหม่ตอนหน้าค่ะ แจ๋ว

Hosted by www.Geocities.ws

1