MFC - Hướng dẫn nhanh

Thư viện Microsoft Foundation Class (MFC) cung cấp một tập hợp các hàm, hằng số, kiểu dữ liệu và lớp để đơn giản hóa việc tạo ứng dụng cho hệ điều hành Microsoft Windows. Trong hướng dẫn này, bạn sẽ tìm hiểu tất cả về cách khởi động và tạo các ứng dụng dựa trên cửa sổ bằng MFC.

Điều kiện tiên quyết

Chúng tôi đã giả định rằng bạn biết những điều sau -

  • Một chút về lập trình cho Windows.
  • Kiến thức cơ bản về lập trình trong C ++.
  • Hiểu các nguyên tắc cơ bản của lập trình hướng đối tượng.

MFC là gì?

Microsoft Foundation Class Library (MFC) là một "khuôn khổ ứng dụng" để lập trình trong Microsoft Windows. MFC cung cấp nhiều mã, được yêu cầu cho những điều sau:

  • Quản lý Windows.
  • Menu và hộp thoại.
  • Thực hiện nhập / xuất cơ bản.
  • Lưu trữ tập hợp các đối tượng dữ liệu, v.v.

Bạn có thể dễ dàng mở rộng hoặc ghi đè chức năng cơ bản của khung MFC trong các ứng dụng C ++ bằng cách thêm mã dành riêng cho ứng dụng của bạn vào khung MFC.

Khung MFC

  • Khung MFC cung cấp một tập hợp các lớp có thể sử dụng lại được thiết kế để đơn giản hóa việc lập trình Windows.

  • MFC cung cấp các lớp cho nhiều đối tượng cơ bản, chẳng hạn như chuỗi, tệp và bộ sưu tập được sử dụng trong lập trình hàng ngày.

  • Nó cũng cung cấp các lớp cho các cấu trúc dữ liệu và API Windows phổ biến, chẳng hạn như cửa sổ, điều khiển và ngữ cảnh thiết bị.

  • Khung cũng cung cấp nền tảng vững chắc cho các tính năng nâng cao hơn, chẳng hạn như ActiveX và xử lý chế độ xem tài liệu.

  • Ngoài ra, MFC cung cấp một khung ứng dụng, bao gồm các lớp tạo nên cấu trúc phân cấp ứng dụng.

Tại sao nên sử dụng MFC?

Khung công tác MFC là một cách tiếp cận mạnh mẽ cho phép bạn xây dựng dựa trên công việc của các lập trình viên chuyên nghiệp cho Windows. Khung MFC có những ưu điểm sau.

  • Nó rút ngắn thời gian phát triển.

  • Nó làm cho mã di động hơn.

  • Nó cũng cung cấp hỗ trợ to lớn mà không làm giảm sự tự do và tính linh hoạt của lập trình.

  • Nó cho phép dễ dàng truy cập vào các phần tử và công nghệ giao diện người dùng "khó lập trình".

  • MFC đơn giản hóa việc lập trình cơ sở dữ liệu thông qua Đối tượng Truy cập Dữ liệu (DAO) và Kết nối Cơ sở Dữ liệu Mở (ODBC), và lập trình mạng thông qua Windows Sockets.

Microsoft Visual C ++ là một môi trường lập trình được sử dụng để tạo các ứng dụng cho hệ điều hành Microsoft Windows. Để sử dụng khung MFC trong ứng dụng C ++ của bạn, bạn phải cài đặt Microsoft Visual C ++ hoặc Microsoft Visual Studio. Microsoft Visual Studio cũng chứa môi trường Microsoft Visual C ++.

Microsoft cung cấp một phiên bản visual studio miễn phí cũng chứa SQL Server và có thể tải xuống từ https://www.visualstudio.com/en-us/downloads/downloadvisual- studio-vs.aspx.

Sau đây là các bước cài đặt.

Step 1- Sau khi Visual Studio được tải xuống, hãy chạy trình cài đặt. Hộp thoại sau sẽ được hiển thị.

Step 2 - Nhấn Install để bắt đầu quá trình cài đặt.

Step 3 - Khi Visual Studio được cài đặt thành công, bạn sẽ thấy hộp thoại sau.

Step 4 - Đóng hộp thoại này và khởi động lại máy tính của bạn nếu được yêu cầu.

Step 5- Mở Visual studio từ menu Start, hộp thoại sau sẽ mở ra. Bạn sẽ mất một khoảng thời gian để chuẩn bị, trong khi bắt đầu lần đầu tiên.

Step 6 - Tiếp theo, bạn sẽ thấy cửa sổ chính của Visual Studio.

Step 7 - Bây giờ bạn đã sẵn sàng để bắt đầu ứng dụng của mình.

Trong chương này, chúng ta sẽ đề cập đến các loại dự án VC ++ khác nhau. Visual Studio bao gồm một số loại mẫu dự án Visual C ++. Các mẫu này giúp tạo cấu trúc chương trình cơ bản, menu, thanh công cụ, biểu tượng, tham chiếu và bao gồm các câu lệnh phù hợp với loại dự án bạn muốn tạo. Sau đây là một số tính năng nổi bật của các mẫu.

  • Nó cung cấp các trình hướng dẫn cho nhiều mẫu dự án này và giúp bạn tùy chỉnh các dự án của mình khi bạn tạo chúng.

  • Sau khi dự án được tạo, bạn có thể xây dựng và chạy ứng dụng.

  • Bạn không phải sử dụng mẫu để tạo dự án, nhưng trong hầu hết các trường hợp, sử dụng mẫu dự án sẽ hiệu quả hơn.

  • Việc sửa đổi cấu trúc và tệp dự án được cung cấp dễ dàng hơn là tạo chúng từ đầu.

Trong MFC, bạn có thể sử dụng các mẫu dự án sau.

Sr.No. Mẫu & Mô tả Dự án
1

MFC Application

Ứng dụng MFC là ứng dụng thực thi dành cho Windows dựa trên Thư viện Microsoft Foundation Class (MFC). Cách dễ nhất để tạo ứng dụng MFC là sử dụng Trình hướng dẫn ứng dụng MFC.

2

MFC ActiveX Control

Các chương trình điều khiển ActiveX là các chương trình mô-đun được thiết kế để cung cấp một loại chức năng cụ thể cho ứng dụng mẹ. Ví dụ: bạn có thể tạo một điều khiển chẳng hạn như một nút để sử dụng trong hộp thoại hoặc thanh công cụ hoặc trên trang Web.

3

MFC DLL

MFC DLL là một tệp nhị phân hoạt động như một thư viện chia sẻ các hàm có thể được sử dụng đồng thời bởi nhiều ứng dụng. Cách dễ nhất để tạo một dự án MFC DLL là sử dụng MFC DLL Wizard.

Sau đây là một số mẫu Chung cũng có thể được sử dụng để tạo ứng dụng MFC -

Sr.No. Mẫu & Mô tả Dự án
1

Empty Project

Dự án là các thùng chứa hợp lý cho mọi thứ cần thiết để xây dựng ứng dụng của bạn. Sau đó, bạn có thể thêm nhiều dự án mới hoặc hiện có vào giải pháp nếu cần.

2

Custom Wizard

Trình hướng dẫn tùy chỉnh Visual C ++ là công cụ để sử dụng khi bạn cần tạo một trình hướng dẫn tùy chỉnh mới. Cách dễ nhất để tạo trình hướng dẫn tùy chỉnh là sử dụng Trình hướng dẫn tùy chỉnh.

Trong chương này, chúng ta sẽ xem xét một ví dụ MFC đang hoạt động. Để tạo ứng dụng MFC, bạn có thể sử dụng trình hướng dẫn để tùy chỉnh các dự án của mình. Bạn cũng có thể tạo một ứng dụng từ đầu.

Tạo dự án bằng mẫu dự án

Sau đây là các bước để tạo một dự án bằng cách sử dụng các mẫu dự án có sẵn trong Visual Studio.

Step 1 - Mở Visual studio và nhấp vào tùy chọn menu File → New → Project.

Step 2 - Bây giờ bạn có thể thấy rằng hộp thoại Dự án mới đang mở.

Step 3 - Từ ngăn bên trái, chọn Mẫu → Visual C ++ → MFC

Step 4 - Trong ngăn giữa, chọn Ứng dụng MFC.

Step 5- Nhập tên dự án 'MFCDemo' vào trường Tên và nhấn OK để tiếp tục. Bạn sẽ thấy hộp thoại sau.

Step 6 - Nhấp vào Tiếp theo.

Step 7 - Chọn các tùy chọn được hiển thị trong hộp thoại ở trên và nhấp vào Tiếp theo.

Step 8 - Bỏ chọn tất cả các tùy chọn và nhấp vào nút Kết thúc.

Bây giờ bạn có thể thấy rằng trình hướng dẫn MFC tạo Hộp thoại này và các tệp dự án theo mặc định.

Step 9 - Chạy ứng dụng này, bạn sẽ thấy kết quả sau.

Tạo dự án từ Scratch

Bạn cũng có thể tạo một ứng dụng MFC từ đầu. Để tạo một ứng dụng MFC, bạn cần làm theo các Bước sau.

Step 1 - Mở Visual studio và nhấp vào tùy chọn menu File → New → Project.

Step 2 - Bây giờ bạn có thể thấy hộp thoại Dự án mới.

Step 3 - Từ khung bên trái, chọn Mẫu → Trực quan C ++ → Chung.

Step 4 - Trong ngăn giữa, chọn Empty

Step 5- Nhập tên dự án 'MFCDemoFromScratch' vào trường Tên và nhấn OK để tiếp tục. Bạn sẽ thấy rằng một dự án trống được tạo.

Step 6 - Để biến nó thành một dự án MFC, nhấp chuột phải vào dự án và chọn Thuộc tính.

Step 7 - Ở phần bên trái, nhấp vào Thuộc tính cấu hình → Chung.

Step 8 - Chọn tùy chọn Use MFC in Shared DLL trong phần Project Defaults và nhấn OK.

Step 9- Vì nó là một dự án trống rỗng bây giờ; chúng ta cần thêm một tệp C ++. Vì vậy, nhấp chuột phải vào dự án và chọn Thêm → Mục mới…

Step 10 - Chọn C++ File (.cpp) trong ngăn giữa và nhập tên tệp vào trường Tên và nhấp vào Thêm nút.

Step 11 - Bây giờ bạn có thể thấy main.cpp tệp được thêm vào thư mục Tệp Nguồn.

Step 12 - Hãy để chúng tôi thêm đoạn mã sau vào tệp này.

#include <iostream> 
using namespace std;  

void main() { 
   cout << "***************************************\n"; 
   cout << "MFC Application Tutorial"; 
   cout << "\n***************************************"; 
   getchar(); 
}

Step 13 - Khi bạn chạy ứng dụng này, bạn sẽ thấy kết quả sau trên bảng điều khiển.

*************************************** 
MFC Application Tutorial 
***************************************

Trong chương này, chúng tôi sẽ trình bày về các nguyên tắc cơ bản của Windows. Để tạo một chương trình, còn gọi là ứng dụng, bạn lấy một lớp từ CWinApp của MFC.CWinApp viết tắt của Class for a Windows Application.

Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một dự án Win32 mới.

Step 1 - Mở Visual studio và nhấp vào tùy chọn menu File → New → Project.

Step 2 - Bây giờ bạn có thể thấy hộp thoại Dự án mới.

Step 3 - Từ khung bên trái, chọn Mẫu → Visual C ++ → Win32.

Step 4 - Trong khung giữa, chọn Win32 Project.

Step 5- Nhập tên dự án 'MFCWindowDemo' vào trường Tên và nhấp OK để tiếp tục. Bạn sẽ thấy hộp thoại sau.

Step 6 - Nhấp vào Tiếp theo.

Step 7 - Chọn các tùy chọn như trong hộp thoại đưa ra ở trên và nhấp vào Hoàn tất.

Step 8 - Một dự án trống được tạo.

Step 9 - Để biến nó thành một dự án MFC, nhấp chuột phải vào dự án và chọn Thuộc tính.

Step 10 - Ở phần bên trái, nhấp vào Thuộc tính cấu hình → Chung.

Step 11 - Chọn tùy chọn Use MFC in Shared DLL trong phần Project Defaults và nhấn OK.

Step 12 - Thêm một tệp nguồn mới.

Step 13 - Nhấp chuột phải vào Dự án của bạn và chọn Thêm → Mục mới ...

Step 14 - Trong phần Mẫu, nhấp vào Tệp C ++ (.cpp).

Step 15 - Đặt Tên làm Ví dụ và nhấp vào Thêm.

Tạo cửa sổ

Bất kỳ ứng dụng nào cũng có hai phần chính -

  • Class
  • Khung hoặc Cửa sổ

Hãy để chúng tôi tạo một cửa sổ theo các bước sau:

Step 1 - Để tạo một ứng dụng, chúng ta cần lấy một lớp từ CWinApp của MFC.

#include
class CExample : public CWinApp {
   BOOL InitInstance() {
      return TRUE;
   }
};

Step 2 - Chúng tôi cũng cần một khung / cửa sổ để hiển thị nội dung ứng dụng của chúng tôi.

Step 3 - Đối với điều này, chúng ta cần thêm một lớp khác và lấy nó từ MFC's CFrameWnd lớp và triển khai phương thức khởi tạo của nó và gọi phương thức Create (), phương thức này sẽ tạo một khung / cửa sổ như được hiển thị trong đoạn mã sau.

class CMyFrame : public CFrameWnd {
   public:
      CMyFrame() {
         Create(NULL, _T("MFC Application Tutorial"));
      }
};

Step 4 - Như bạn có thể thấy rằng phương thức Create () cần hai tham số, tên của lớp, sẽ được truyền là NULL và tên của cửa sổ, là chuỗi sẽ được hiển thị trên thanh tiêu đề.

Cửa sổ chính

Sau khi tạo một cửa sổ, để cho phép ứng dụng sử dụng, bạn có thể sử dụng một con trỏ để hiển thị lớp được sử dụng để tạo cửa sổ. Trong trường hợp này, con trỏ sẽ là CFrameWnd. Để sử dụng cửa sổ khung, hãy gán con trỏ của nó cho biến thành viên CWinThread :: m_pMainWnd. Điều này được thực hiện trong triển khai InitInstance () của ứng dụng của bạn.

Step 1 - Đây là việc thực thi InitInstance () trong lớp CExample.

class CExample : public CWinApp {
   BOOL InitInstance() {
      CMyFrame *Frame = new CMyFrame();  m_pMainWnd = Frame;
      
      Frame->ShowWindow(SW_NORMAL);
      Frame->UpdateWindow();
      
      return TRUE;
   }
};

Step 2 - Sau đây là phần triển khai hoàn chỉnh của tệp tin example.cpp.

#include <afxwin.h>

class CMyFrame : public CFrameWnd {
   public:
      CMyFrame() {
         Create(NULL, _T("MFC Application Tutorial"));
      }
};

class CExample : public CWinApp {
   BOOL InitInstance() {
      CMyFrame *Frame = new CMyFrame();
      m_pMainWnd = Frame;
      
      Frame->ShowWindow(SW_NORMAL);
      Frame->UpdateWindow();
      
      return TRUE;
   }
};

CExample theApp;

Step 3 - Khi chúng ta chạy ứng dụng trên, cửa sổ sau được tạo.

Kiểu Windows

Kiểu Windows là đặc điểm kiểm soát các tính năng như giao diện cửa sổ, đường viền, trạng thái thu nhỏ hoặc tối đa hoặc các trạng thái thay đổi kích thước khác, v.v.

Sr.No. Phong cách & Mô tả
1

WS_BORDER

Tạo một cửa sổ có đường viền.

2

WS_CAPTION

Tạo cửa sổ có thanh tiêu đề (ngụ ý kiểu WS_BORDER). Không thể sử dụng với kiểu WS_DLGFRAME.

3

WS_CHILD

Tạo một cửa sổ con. Không thể sử dụng với kiểu WS_POPUP.

4

WS_CHILDWINDOW

Giống như kiểu WS_CHILD.

5

WS_CLIPCHILDREN

Loại trừ khu vực bị chiếm bởi các cửa sổ con khi bạn vẽ trong cửa sổ mẹ. Được sử dụng khi bạn tạo cửa sổ mẹ.

6

WS_CLIPSIBLINGS

Cắt các cửa sổ con tương đối với nhau; nghĩa là, khi một cửa sổ con cụ thể nhận được thông báo sơn, kiểu WS_CLIPSIBLINGS sẽ cắt tất cả các cửa sổ con chồng chéo khác ra khỏi vùng của cửa sổ con sẽ được cập nhật. (Nếu WS_CLIPSIBLINGS không được cung cấp và các cửa sổ con chồng lên nhau, khi bạn vẽ trong vùng máy khách của cửa sổ con, bạn có thể vẽ trong vùng máy khách của cửa sổ con lân cận.) Chỉ để sử dụng với kiểu WS_CHILD.

7

WS_DISABLED

Tạo một cửa sổ ban đầu bị tắt.

số 8

WS_DLGFRAME

Tạo một cửa sổ có đường viền kép nhưng không có tiêu đề.

9

WS_GROUP

Chỉ định điều khiển đầu tiên của một nhóm điều khiển trong đó người dùng có thể di chuyển từ điều khiển này sang điều khiển tiếp theo bằng các phím mũi tên. Tất cả các điều khiển được xác định với kiểu WS_GROUP FALSE sau điều khiển đầu tiên thuộc cùng một nhóm. Điều khiển tiếp theo với kiểu WS_GROUP bắt đầu nhóm tiếp theo (nghĩa là một nhóm kết thúc khi nhóm tiếp theo bắt đầu).

10

WS_HSCROLL

Tạo cửa sổ có thanh cuộn ngang.

11

WS_ICONIC

Tạo một cửa sổ ban đầu được thu nhỏ. Giống như kiểu WS_MINIMIZE.

12

WS_MAXIMIZE

Tạo một cửa sổ có kích thước tối đa.

13

WS_MAXIMIZEBOX

Tạo cửa sổ có nút Phóng to.

14

WS_MINIMIZE

Tạo một cửa sổ ban đầu được thu nhỏ. Chỉ để sử dụng với kiểu WS_OVERLAPPED.

15

WS_MINIMIZEBOX

Tạo một cửa sổ có nút Thu nhỏ.

16

WS_OVERLAPPED

Tạo một cửa sổ chồng chéo. Một cửa sổ chồng chéo thường có chú thích và đường viền.

17

WS_OVERLAPPED WINDOW

Tạo một cửa sổ chồng chéo với các kiểu WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX và WS_MAXIMIZEBOX.

18

WS_POPUP

Tạo một cửa sổ bật lên. Không thể sử dụng với kiểu WS_CHILD.

19

WS_POPUPWINDOW

Tạo cửa sổ bật lên với các kiểu WS_BORDER, WS_POPUP và WS_SYSMENU. Kiểu WS_CAPTION phải được kết hợp với kiểu WS_POPUPWINDOW để hiển thị menu Điều khiển.

20

WS_SIZEBOX

Tạo một cửa sổ có đường viền định cỡ. Giống như kiểu WS_THICKFRAME.

21

WS_SYSMENU

Tạo một cửa sổ có hộp menu Điều khiển trên thanh tiêu đề. Chỉ được sử dụng cho các cửa sổ có thanh tiêu đề.

22

WS_TABSTOP

Chỉ định một trong bất kỳ số lượng điều khiển nào mà người dùng có thể di chuyển bằng cách sử dụng phím TAB. Phím TAB chuyển người dùng sang điều khiển tiếp theo được chỉ định bởi kiểu WS_TABSTOP.

23

WS_THICKFRAME

Tạo một cửa sổ với khung dày có thể được sử dụng để kích thước cửa sổ.

24

WS_TILED

Tạo một cửa sổ chồng chéo. Cửa sổ chồng chéo có thanh tiêu đề và đường viền. Giống như kiểu WS_OVERLAPPED.

25

WS_TILEDWINDOW

Tạo một cửa sổ chồng chéo với các kiểu WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX và WS_MAXIMIZEBOX. Giống như kiểu WS_OVERLAPPEDWINDOW.

26

WS_VISIBLE

Tạo một cửa sổ hiển thị ban đầu.

27

WS_VSCROLL

Tạo cửa sổ có thanh cuộn dọc.

Step 1- Chúng ta hãy xem xét một ví dụ đơn giản, trong đó chúng ta sẽ thêm một số kiểu dáng. Sau khi tạo một cửa sổ, để hiển thị nó cho người dùng, chúng ta có thể áp dụng kiểu WS_VISIBLE cho nó và thêm vào đó, chúng ta cũng sẽ thêm kiểu WS_OVERLAPPED. Đây là một triển khai -

class CMyFrame : public CFrameWnd {
   public:
      CMyFrame() {
         Create(NULL, _T("MFC Application Tutorial"), WS_VISIBLE | WS_OVERLAPPED);
      }
};

Step 2 - Khi bạn chạy ứng dụng này, cửa sổ sau sẽ được tạo.

Bây giờ bạn có thể thấy rằng các tùy chọn thu nhỏ, tối đa hóa và đóng không xuất hiện nữa.

Vị trí Windows

Để xác định vị trí những thứ hiển thị trên màn hình, máy tính sử dụng một hệ tọa độ tương tự như hệ Descartes, nhưng điểm gốc nằm ở góc trên cùng bên trái của màn hình. Sử dụng hệ tọa độ này, bất kỳ điểm nào cũng có thể được định vị theo khoảng cách từ góc trên cùng bên trái của màn hình theo trục ngang và trục dọc.

Các Win32 library cung cấp một cấu trúc được gọi là POINT được định nghĩa như sau:

typedef struct tagPOINT {
   LONG x;
   LONG y;
} POINT;
  • Biến thành viên 'x' là khoảng cách từ đường viền bên trái của màn hình đến điểm.

  • Biến 'y' đại diện cho khoảng cách từ đường viền trên cùng của màn hình đến điểm.

  • Bên cạnh cấu trúc POINT của Win32, thư viện Microsoft Foundation Class (MFC) cung cấp lớp CPoint.

  • Điều này cung cấp chức năng tương tự như cấu trúc POINT. Là một lớp C ++, nó bổ sung thêm nhiều chức năng cần thiết để định vị một điểm. Nó cung cấp hai hàm tạo.

CPoint();
CPoint(int X, int Y);

Kích thước Windows

Trong khi một điểm được sử dụng để định vị một đối tượng trên màn hình, mỗi cửa sổ có một kích thước. Kích thước cung cấp hai thước đo liên quan đến một đối tượng.

  • Chiều rộng của một đối tượng.
  • Chiều cao của một đối tượng.

Thư viện Win32 sử dụng cấu trúc SIZE được định nghĩa như sau:

typedef struct tagSIZE {
   int cx;
   int cy;
} SIZE;

Bên cạnh cấu trúc SIZE của Win32, MFC cung cấp lớp CSize. Lớp này có chức năng tương tự như SIZE nhưng thêm các tính năng của một lớp C ++. Nó cung cấp năm hàm tạo cho phép bạn tạo biến kích thước theo bất kỳ cách nào bạn chọn.

CSize();
CSize(int initCX, int initCY);
CSize(SIZE initSize);
CSize(POINT initPt);
CSize(DWORD dwSize);

Kích thước Windows

Khi một Cửa sổ hiển thị, nó có thể được xác định trên màn hình theo vị trí của nó liên quan đến các đường viền của màn hình. Một Cửa sổ cũng có thể được xác định bằng chiều rộng và chiều cao của nó. Những đặc điểm này được quy định hoặc điều khiển bởi rect lập luận củaCreate()phương pháp. Đối số này là một hình chữ nhật có thể được tạo thông qua cấu trúc Win32 RECT.

typedef struct _RECT {
   LONG left;
   LONG top;
   LONG right;
   LONG bottom;
} RECT, *PRECT;

Bên cạnh Win32's RECT cấu trúc, MFC cung cấp lớp CRect có các hàm tạo sau:

CRect();
CRect(int l, int t, int r, int b);
CRect(const RECT& srcRect);
CRect(LPCRECT lpSrcRect);
CRect(POINT point, SIZE size);
CRect(POINT topLeft, POINT bottomRight);

Chúng ta hãy xem xét một ví dụ đơn giản, trong đó chúng ta sẽ chỉ định vị trí và kích thước của cửa sổ

class CMyFrame : public CFrameWnd {
   public:
      CMyFrame() {
         Create(NULL, _T("MFC Application Tutorial"), WS_SYSMENU, CRect(90, 120, 
            550, 480));
      }
};

Khi bạn chạy ứng dụng này, cửa sổ sau được tạo ở góc trên cùng bên trái của màn hình như được chỉ định trong hàm tạo CRect trong hai tham số đầu tiên. Hai tham số cuối cùng là kích thước của Cửa sổ.

Cha mẹ Windows

Trong thế giới thực, nhiều ứng dụng được tạo từ các Windows khác nhau. Khi một ứng dụng sử dụng Windows khác nhau, hầu hết các đối tượng phụ thuộc vào một đối tượng cụ thể. Nó có thể là Cửa sổ đầu tiên đã được tạo hoặc một cửa sổ khác mà bạn đã chỉ định. Cửa sổ như vậy được gọi làParent Window. Tất cả các cửa sổ khác phụ thuộc vào nó trực tiếp hoặc gián tiếp.

  • Nếu Cửa sổ bạn đang tạo phụ thuộc vào một cửa sổ khác, bạn có thể chỉ định rằng nó có một cửa sổ cha.

  • Điều này được thực hiện với đối số pParentWnd của phương thức CFrameWnd :: Create ().

  • Nếu Cửa sổ không có cha, hãy truyền đối số có giá trị NULL.

Chúng ta hãy xem xét một ví dụ chỉ có một Cửa sổ và không có Cửa sổ mẹ nào có sẵn, vì vậy chúng ta sẽ chuyển đối số với giá trị NULL như được hiển thị trong đoạn mã sau:

class CMyFrame : public CFrameWnd {
   public:
      CMyFrame() {
         Create(NULL, _T("MFC Application Tutorial"), WS_SYSMENU, 
            CRect(90, 120, 550, 480), NULL);
      }
};

Khi bạn chạy ứng dụng trên, bạn sẽ thấy kết quả tương tự.

Trong chương này, chúng ta sẽ đề cập đến các Hộp thoại. Các ứng dụng dành cho Windows thường xuyên giao tiếp với người dùng thông qua các hộp thoại.CDialog classcung cấp một giao diện để quản lý các hộp thoại. Trình chỉnh sửa hộp thoại Visual C ++ giúp dễ dàng thiết kế hộp thoại và tạo tài nguyên mẫu hộp thoại của chúng.

  • Tạo một đối tượng hộp thoại là một hoạt động hai giai đoạn -

    • Xây dựng đối tượng hộp thoại.

    • Tạo cửa sổ hộp thoại.

Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một dự án Win32 mới.

Step 1 - Mở Visual studio và nhấp vào tùy chọn menu File → New → Project.

Step 2 - Bây giờ bạn có thể thấy hộp thoại Dự án mới.

Step 3 - Từ khung bên trái, chọn Mẫu → Visual C ++ → Win32.

Step 4 - Trong khung giữa, chọn Win32 Project.

Step 5- Nhập tên dự án 'MFCDialogDemo' vào trường Tên và nhấp OK để tiếp tục. Bạn sẽ thấy hộp thoại sau.

Step 6 - Nhấp vào Tiếp theo.

Step 7 - Chọn các tùy chọn hiển thị trong hộp thoại ở trên và nhấp vào Kết thúc.

Step 8 - Một dự án trống được tạo.

Step 9 - Để biến nó thành một dự án MFC, nhấp chuột phải vào dự án và chọn Thuộc tính.

Step 10 - Ở phần bên trái, nhấp vào Thuộc tính cấu hình → Chung.

Step 11 - Chọn tùy chọn Use MFC in Shared DLL trong phần Project Defaults và nhấn OK.

Step 12 - Thêm một tệp nguồn mới.

Step 13 - Nhấp chuột phải vào Dự án của bạn và chọn Thêm → Mục mới.

Step 14 - Trong phần Mẫu, nhấp vào Tệp C ++ (.cpp)

Step 15 - Đặt Tên làm Ví dụ và nhấp vào Thêm.

Step 16 - Để tạo một ứng dụng, chúng ta cần thêm một lớp và lấy nó từ CWinApp của MFC.

#include <afxwin.h>

class CExample : public CWinApp {
   public:
      BOOL InitInstance();
};

Tạo hộp thoại

Step 1 - Để tạo hộp thoại, nhấp chuột phải vào thư mục Resource Files trong giải pháp explorer và chọn Add → Resource.

Step 2 - Trong hộp thoại Thêm tài nguyên, chọn Hộp thoại và nhấp vào Mới.

Step 3 - Một hộp thoại yêu cầu một số chuẩn bị trước khi thực sự tạo nó theo chương trình.

Step 4 - Một hộp thoại trước tiên có thể được tạo theo cách thủ công dưới dạng tệp văn bản (trong tệp tài nguyên).

Step 5 - Bây giờ bạn có thể thấy tệp MFCDialogDemo.rc được tạo trong Tệp Tài nguyên.

Step 6- Tệp tài nguyên được mở trong trình thiết kế. Tương tự có thể được mở dưới dạng tệp văn bản. Nhấp chuột phải vào tệp tài nguyên và chọn Mở bằng.

Step 7 - Chọn trình soạn thảo Mã nguồn (Văn bản) và nhấp vào nút Thêm.

Step 8 - Quay lại trình thiết kế và nhấp chuột phải vào hộp thoại và chọn Thuộc tính.

Step 9 - Bạn cần phải chọn trong số nhiều tùy chọn.

Step 10- Giống như hầu hết các điều khiển khác, một hộp thoại phải được xác định. Định danh (ID) của một hộp thoại thường bắt đầu bằng IDD_, Chúng ta hãy thay đổi ID thành IDD_EXAMPLE_DLG.

Vị trí hộp thoại

Một hộp thoại phải được đặt ở vị trí “vật lý” trên một ứng dụng. Bởi vì một hộp thoại thường được tạo dưới dạng cha cho các điều khiển khác, vị trí của nó phụ thuộc vào mối quan hệ của nó với cửa sổ cha hoặc với màn hình nền.

Nếu bạn nhìn và cửa sổ Thuộc tính, bạn sẽ thấy hai trường, X Pos và Y Pos.

  • X là khoảng cách từ đường viền bên trái của màn hình đến đường viền bên trái của hộp thoại.

  • Y là khoảng cách từ đường viền trên cùng của màn hình đến đường viền trên cùng của hộp thoại.

Theo mặc định, các trường này được đặt thành không. Bạn cũng có thể thay đổi như hình trên.

Nếu bạn chỉ định hai kích thước này là 0, các đường viền bên trái và trên cùng của hộp thoại sẽ được đặt để đối tượng xuất hiện ở giữa màn hình.

Kích thước hộp thoại

Kích thước của hộp thoại liên quan đến chiều rộng và chiều cao của nó. Bạn có thể thay đổi kích thước chiều rộng và chiều cao với sự trợ giúp của chuột trong cửa sổ thiết kế.

Bạn có thể thấy những thay đổi về chiều rộng và chiều cao trên Thanh trạng thái.

Phương thức hộp thoại

Lớp cơ sở được sử dụng để hiển thị các hộp thoại trên màn hình là lớp CDialog. Để tạo một hộp thoại, chúng ta cần lấy một lớp từ CDialog. Bản thân lớp CDialog cung cấp ba hàm tạo như sau:

CDialog();
CDialog(UINT nIDTemplate, CWnd* pParentWnd = NULL);
CDialog(LPCTSTR lpszTemplateName, CWnd* pParentWnd = NULL);

Hãy để chúng tôi tạo một lớp CExampleDlg khác và lấy nó từ CDialog. Chúng tôi sẽ triển khai hàm hủy phương thức khởi tạo mặc định của nó như được hiển thị trong đoạn mã sau.

class CExampleDlg : public CDialog {
   public:
      enum { IDD = IDD_EXAMPLE_DLG };
   
      CExampleDlg();
      ~CExampleDlg();
};

CExampleDlg::CExampleDlg():CDialog(CExampleDlg::IDD) {

}

CExampleDlg::~CExampleDlg() {

}

Chúng ta cần khởi tạo hộp thoại này trên phương thức CExample :: InitInstance () như được hiển thị trong đoạn mã sau.

BOOL CExample::InitInstance() {
   CExampleDlg myDlg;
   m_pMainWnd = &myDlg;
   
   return TRUE;
}

Hộp thoại phương thức

Có hai loại hộp thoại - modelessmodal. Hộp thoại modal và modeless khác nhau theo quy trình được sử dụng để tạo và hiển thị chúng.

Hộp thoại Modeless

  • Đối với hộp thoại không có mô hình, bạn phải cung cấp phương thức khởi tạo công khai của riêng bạn trong lớp hộp thoại của bạn.

  • Để tạo một hộp thoại không có mô hình, hãy gọi hàm tạo công khai của bạn, sau đó gọi hàm Tạo thành viên của đối tượng hộp thoại để tải tài nguyên hộp thoại.

  • Bạn có thể gọi Create trong hoặc sau cuộc gọi hàm tạo. Nếu tài nguyên hộp thoại có thuộc tính WS_VISIBLE, hộp thoại sẽ xuất hiện ngay lập tức.

  • Nếu không, bạn phải gọi hàm thành viên ShowWindow của nó.

Hộp thoại phương thức

  • Để tạo một hộp thoại phương thức, hãy gọi một trong hai hàm tạo công khai được khai báo trong CDialog.

  • Tiếp theo, gọi đối tượng hộp thoại DoModal chức năng thành viên để hiển thị hộp thoại và quản lý tương tác với nó cho đến khi người dùng chọn OK hoặc Cancel.

  • Sự quản lý này của DoModal là điều làm cho hộp thoại trở thành phương thức. Đối với hộp thoại phương thức, DoModal tải tài nguyên hộp thoại.

Step 1 - Để hiển thị hộp thoại dưới dạng phương thức, trong sự kiện CExample :: InitInstance (), hãy gọi phương thức DoModal () bằng cách sử dụng biến hộp thoại của bạn -

BOOL CExample::InitInstance() {
   CExampleDlg myDlg;
   m_pMainWnd = &myDlg;
   myDlg.DoModal();
   return TRUE;
}

Step 2 - Đây là phần triển khai hoàn chỉnh của tập tin Example.cpp.

#include <afxwin.h>
#include "resource.h"

class CExample : public CWinApp {
   public:
      BOOL InitInstance();
};
   
class CExampleDlg : public CDialog {
   public:
      enum { IDD = IDD_EXAMPLE_DLG };
   
      CExampleDlg();
     ~CExampleDlg();
};

CExampleDlg::CExampleDlg():CDialog(CExampleDlg::IDD) {

}

CExampleDlg::~CExampleDlg() {

}

BOOL CExample::InitInstance() {
   CExampleDlg myDlg;
   m_pMainWnd = &myDlg;
   myDlg.DoModal();
   return TRUE;
}
CExample MyApp;

Step 3 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy hộp thoại sau.

Ứng dụng dựa trên hộp thoại

Microsoft Visual Studio cung cấp một cách dễ dàng hơn để tạo một ứng dụng chủ yếu dựa trên hộp thoại. Dưới đây là các bước để tạo một dự án cơ sở hộp thoại bằng cách sử dụng các mẫu dự án có sẵn trong Visual Studio -

Step 1- Mở Visual studio và nhấp vào tùy chọn menu File → New → Project. Bạn có thể thấy hộp thoại Dự án mới.

Step 2 - Từ khung bên trái, chọn Mẫu → Visual C ++ → MFC.

Step 3 - Trong ngăn giữa, chọn Ứng dụng MFC.

Step 4- Nhập tên dự án 'MFCModalDemo' vào trường Tên và nhấp OK để tiếp tục. Bạn sẽ thấy hộp thoại sau.

Step 5 - Nhấp vào Tiếp theo.

Step 6 - Chọn các tùy chọn hiển thị trong hộp thoại trên và nhấp vào Tiếp theo.

Step 7 - Đánh dấu vào tất cả các tùy chọn mà bạn chọn có trên hộp thoại như Tối đa hóa và Thu nhỏ Hộp và nhấp vào Tiếp theo.

Step 8 - Nhấp vào Tiếp theo.

Step 9- Nó sẽ tạo ra hai lớp này. Bạn có thể thay đổi tên của các lớp và nhấp vào Kết thúc.

Step 10 - Bây giờ bạn có thể thấy rằng trình hướng dẫn MFC tạo Hộp thoại này và các tệp dự án theo mặc định.

Step 11 - Khi bạn chạy ứng dụng này, bạn sẽ thấy kết quả sau.

A resourcelà một tệp văn bản cho phép trình biên dịch quản lý các đối tượng như hình ảnh, âm thanh, con trỏ chuột, hộp thoại, v.v. Microsoft Visual Studio giúp việc tạo tệp tài nguyên đặc biệt dễ dàng bằng cách cung cấp các công cụ cần thiết trong cùng một môi trường được sử dụng để lập trình. Điều này có nghĩa là bạn thường không phải sử dụng ứng dụng bên ngoài để tạo hoặc định cấu hình tệp tài nguyên. Sau đây là một số tính năng quan trọng liên quan đến tài nguyên.

  • Tài nguyên là các phần tử giao diện cung cấp thông tin cho người dùng.

  • Bitmap, biểu tượng, thanh công cụ và con trỏ đều là tài nguyên.

  • Một số tài nguyên có thể được điều khiển để thực hiện một hành động như chọn từ menu hoặc nhập dữ liệu vào hộp thoại.

  • Một ứng dụng có thể sử dụng các tài nguyên khác nhau hoạt động độc lập với nhau, các tài nguyên này được nhóm thành một tệp văn bản có phần mở rộng là * .rc.

  • Hầu hết tài nguyên được tạo bằng cách chọn tài nguyên mong muốn từ hộp thoại Thêm tài nguyên.

  • Hộp thoại Thêm tài nguyên cung cấp một danh sách mở rộng các tài nguyên có thể được sử dụng theo yêu cầu, nhưng nếu bạn cần thứ gì đó không có sẵn thì bạn có thể thêm thủ công vào tệp * .rc trước khi thực thi chương trình.

Định danh

An identifierlà một ký hiệu là một số nguyên không đổi có tên thường bắt đầu bằng ID. Nó bao gồm hai phần - một chuỗi văn bản (tên ký hiệu) được ánh xạ tới một giá trị số nguyên (giá trị ký hiệu).

  • Các ký hiệu cung cấp một cách mô tả đề cập đến các tài nguyên và các đối tượng giao diện người dùng, cả trong mã nguồn của bạn và trong khi bạn đang làm việc với chúng trong trình chỉnh sửa tài nguyên.

  • Khi bạn tạo một tài nguyên hoặc đối tượng tài nguyên mới, resource editors cung cấp tên mặc định cho tài nguyên, ví dụ: IDC_DIALOG1 và gán giá trị cho nó.

  • Định nghĩa tên-cộng-giá trị được lưu trữ trong tệp Resource.h.

Step 1 - Hãy để chúng tôi xem xét của chúng tôi CMFCDialogDemo ví dụ từ chương trước, trong đó chúng ta đã tạo một hộp thoại và ID của nó là IDD_EXAMPLE_DLG.

Step 2- Vào Solution Explorer, bạn sẽ thấy tệp resource.h trong Header Files. Tiếp tục bằng cách mở tệp này trong trình chỉnh sửa và bạn sẽ thấy mã định danh hộp thoại và giá trị số nguyên của nó.

Biểu tượng

An iconlà một hình ảnh nhỏ được sử dụng trên cửa sổ đại diện cho một ứng dụng. Nó được sử dụng trong hai trường hợp chính.

  • Trên khung của Cửa sổ, nó được hiển thị ở phía bên trái của tên Cửa sổ trên thanh tiêu đề.

  • Trong Windows Explorer, trên Màn hình nền, trong Máy tính của tôi hoặc trong cửa sổ Bảng điều khiển.

Nếu bạn nhìn vào ví dụ MFCModalDemo của chúng tôi, bạn sẽ thấy rằng Visual studio đang sử dụng biểu tượng mặc định cho thanh tiêu đề như được hiển thị trong ảnh chụp nhanh sau đây.

Bạn có thể tạo biểu tượng của riêng mình bằng cách làm theo các bước dưới đây -

Step 1 - Nhấp chuột phải vào dự án của bạn và chọn Add → Resources, bạn sẽ thấy hộp thoại Add Resources.

Step 2 - Chọn Biểu tượng và nhấp vào nút Mới và bạn sẽ thấy biểu tượng sau.

Step 3- Trong Solution Explorer, chuyển đến Resource View và mở rộng MFCModalDemo> Icon. Bạn sẽ thấy hai biểu tượng. IDR_MAINFRAME là biểu tượng mặc định và IDI_ICON1 là biểu tượng mới được tạo.

Step 4 - Nhấp chuột phải vào biểu tượng mới Tạo và chọn Thuộc tính.

Step 5 - IDI_ICON1 là ID của biểu tượng này, bây giờ Hãy để chúng tôi thay đổi ID này thành IDR_MYICON.

Step 6- Bây giờ bạn có thể thay đổi biểu tượng này trong trình thiết kế theo yêu cầu của bạn. Chúng tôi sẽ sử dụng cùng một biểu tượng.

Step 7 - Lưu biểu tượng này.

Step 8 - Chuyển đến hàm tạo CMFCModalDemoDlg trong tệp CMFCModalDemoDlg.cpp sẽ giống như đoạn mã sau.

CMFCModalDemoDlg::CMFCModalDemoDlg(CWnd* pParent /* = NULL*/)
   : CDialogEx(IDD_MFCMODALDEMO_DIALOG, pParent) {
   m_hIcon = AfxGetApp() -> LoadIcon(IDR_MAINFRAME);
}

Step 9- Bây giờ bạn có thể thấy rằng biểu tượng mặc định được tải trong hàm tạo. Hãy để chúng tôi thay đổi nó thành IDR_ MYICON như được hiển thị trong mã sau.

CMFCModalDemoDlg::CMFCModalDemoDlg(CWnd* pParent /* = NULL*/)
   : CDialogEx(IDD_MFCMODALDEMO_DIALOG, pParent) {
   m_hIcon = AfxGetApp() -> LoadIcon(IDR_ MYICON);
}

Step 10 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy biểu tượng mới được hiển thị trên hộp thoại.

Thực đơn

Menuscho phép bạn sắp xếp các lệnh một cách hợp lý và dễ tìm. Với trình chỉnh sửa Menu, bạn có thể tạo và chỉnh sửa menu bằng cách làm việc trực tiếp với thanh menu gần giống với thanh menu trong ứng dụng đã hoàn thành của bạn. Để tạo menu, hãy làm theo các bước dưới đây:

Step 1- Nhấp chuột phải vào dự án của bạn và chọn Thêm → Tài nguyên. Bạn sẽ thấy hộp thoại Thêm tài nguyên.

Step 2- Chọn Menu và nhấp vào Mới. Bạn sẽ thấy hình chữ nhật có chứa "Type Here" trên thanh menu.

Step 3 - Viết một số tùy chọn menu như Tệp, Chỉnh sửa, v.v. như được hiển thị trong ảnh chụp sau.

Step 4- Nếu bạn mở rộng thư mục Menu trong Chế độ xem tài nguyên, bạn sẽ thấy mã định danh Menu IDR_MENU1. Nhấp chuột phải vào mã định danh này và thay đổi nó thành IDM_MAINMENU.

Step 5 - Lưu tất cả các thay đổi.

Step 6- Chúng ta cần đính kèm menu này vào hộp thoại của chúng ta. Mở rộng thư mục Hộp thoại của bạn trong Giải pháp Explorer và nhấp đúp vào mã định danh hộp thoại.

Step 7- Bạn sẽ thấy trường menu trong Thuộc tính. Chọn mã định danh Menu từ menu thả xuống như được hiển thị ở trên.

Step 8 - Chạy ứng dụng này và bạn sẽ thấy hộp thoại sau đây cũng chứa các tùy chọn menu.

Thanh công cụ

A toolbar là một điều khiển Windows cho phép người dùng thực hiện một số hành động trên biểu mẫu bằng cách nhấp vào nút thay vì sử dụng menu.

  • Thanh công cụ cung cấp một nhóm nút thuận tiện giúp đơn giản hóa công việc của người dùng bằng cách đưa các hành động dễ tiếp cận nhất dưới dạng nút.

  • Thanh công cụ có thể đưa các hành động phổ biến như vậy đến gần hơn với người dùng.

  • Thanh công cụ thường hiển thị dưới menu chính.

  • Chúng có thể được trang bị các nút nhưng đôi khi các nút hoặc một số nút của chúng có chú thích.

  • Thanh công cụ cũng có thể được trang bị với các loại điều khiển khác.

Để tạo một thanh công cụ, sau đây là các bước.

Step 1- Nhấp chuột phải vào dự án của bạn và chọn Thêm → Tài nguyên. Bạn sẽ thấy hộp thoại Thêm tài nguyên.

Step 2- Chọn Thanh công cụ và nhấp vào Mới. Bạn sẽ thấy màn hình sau.

Step 3 - Thiết kế thanh công cụ của bạn trong trình thiết kế như được hiển thị trong ảnh chụp màn hình sau và chỉ định cả ID.

Step 4 - Thêm hai biến này trong lớp CMFCModalDemoDlg.

CToolBar m_wndToolBar;
   BOOL butD;

Step 5 - Sau đây là quá trình triển khai hoàn chỉnh CMFCModalDemoDlg trong tệp CMFCModalDemoDlg.h -

class CMFCModalDemoDlg : public CDialogEx {
   // Construction
   public:
      CMFCModalDemoDlg(CWnd* pParent = NULL); // standard constructor
   // Dialog Data
   #ifdef AFX_DESIGN_TIME
      enum { IDD = IDD_MFCMODALDEMO_DIALOG };
   #endif

   protected:
      virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
   
   // Implementation
   protected:
      HICON m_hIcon;
      CToolBar m_wndToolBar;
      BOOL butD;
   
      // Generated message map functions
      virtual BOOL OnInitDialog();
      afx_msg void OnPaint();
      afx_msg HCURSOR OnQueryDragIcon();
      DECLARE_MESSAGE_MAP()
	
   public:
      afx_msg void OnBnClickedOk();
};

Step 6 - Cập nhật CMFCModalDemoDlg :: OnInitDialog () như trong đoạn mã sau.

BOOL CMFCModalDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();
   
   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);       // Set big icon
   SetIcon(m_hIcon, FALSE);      // Set small icon
   
   if (!m_wndToolBar.Create(this)
      || !m_wndToolBar.LoadToolBar(IDR_TOOLBAR1))
      //if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD |
      // WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS |
      // CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
      // !m_wndToolBar.LoadToolBar(IDR_TOOLBAR1)) {
         TRACE0("Failed to Create Dialog Toolbar\n");
         EndDialog(IDCANCEL);
      }
      butD = TRUE;
      CRect rcClientOld; // Old Client Rect
      CRect rcClientNew; // New Client Rect with Tollbar Added
		
      // Retrive the Old Client WindowSize
      // Called to reposition and resize control bars in the client area of a window
      // The reposQuery FLAG does not really traw the Toolbar. It only does the calculations.
      // And puts the new ClientRect values in rcClientNew so we can do the rest of the Math.
      
      GetClientRect(rcClientOld);
      RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0, reposQuery, rcClientNew);
      // All of the Child Windows (Controls) now need to be moved so the Tollbar does not cover them up.
      // Offest to move all child controls after adding Tollbar 
      CPoint ptOffset(rcClientNew.left - rcClientOld.left, rcClientNew.top - rcClientOld.top); 
		 
      CRect rcChild;
      CWnd* pwndChild = GetWindow(GW_CHILD); //Handle to the Dialog Controls
      
      while (pwndChild) // Cycle through all child controls {
         pwndChild -> GetWindowRect(rcChild); // Get the child control RECT
         ScreenToClient(rcChild);
          
         // Changes the Child Rect by the values of the claculated offset
         rcChild.OffsetRect(ptOffset);
         pwndChild -> MoveWindow(rcChild, FALSE); // Move the Child Control
         pwndChild = pwndChild -> GetNextWindow();
      }
       
      CRect rcWindow;
      // Get the RECT of the Dialog
      GetWindowRect(rcWindow);
       
      // Increase width to new Client Width
      rcWindow.right += rcClientOld.Width() - rcClientNew.Width();
       
      // Increase height to new Client Height
       rcWindow.bottom += rcClientOld.Height() - rcClientNew.Height();
      // Redraw Window
      MoveWindow(rcWindow, FALSE);
       
      // Now we REALLY Redraw the Toolbar
      RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);
       
   // TODO: Add extra initialization here

   return TRUE; // return TRUE unless you set the focus to a control
}

Step 7- Chạy ứng dụng này. Bạn sẽ thấy hộp thoại sau đây cũng chứa thanh công cụ.

Máy gia tốc

An access keylà một ký tự cho phép người dùng thực hiện thao tác trên menu nhanh hơn bằng cách sử dụng bàn phím thay vì chuột. Điều này thường nhanh hơn vì người dùng sẽ không cần đặt chuột ở bất kỳ đâu, điều này giúp giảm thời gian thực hiện hành động.

Step 1 - Để tạo khóa truy cập, hãy nhập dấu và "&" ở bên trái của mục menu.

Step 2- Lặp lại bước này cho tất cả các tùy chọn menu. Chạy ứng dụng này và nhấn Alt. Bạn sẽ thấy rằng chữ cái đầu tiên của tất cả các tùy chọn menu đều được gạch dưới.

Phím tắt

Phím tắt là một phím hoặc một tổ hợp các phím được người dùng nâng cao sử dụng để thực hiện một hành động mà nếu không sẽ được thực hiện trên một mục menu. Hầu hết các phím tắt là sự kết hợp của phím Ctrl được nhấn đồng thời với phím chữ cái. Ví dụ: Ctrl + N, Ctrl + O hoặc Ctrl + D.

Để tạo lối tắt, ở phía bên phải của chuỗi tạo chú thích menu, hãy nhấp chuột phải vào mục menu và chọn thuộc tính.

Trong trường Phụ đề, nhập \ t theo sau là kết hợp mong muốn như được hiển thị bên dưới cho tùy chọn menu Mới. Lặp lại bước cho tất cả các tùy chọn menu.

Bảng tăng tốc

Bảng Accelerator là danh sách các mục trong đó mỗi mục của bảng kết hợp một số nhận dạng, một phím tắt và một số không đổi để chỉ định loại phím tăng tốc. Cũng giống như các tài nguyên khác, bảng tăng tốc có thể được tạo theo cách thủ công trong tệp .rc. Sau đây là các bước để tạo một bảng gia tốc.

Step 1 - Để tạo bảng gia tốc, nhấp chuột phải vào tệp * .rc trong trình khám phá giải pháp.

Step 2 - Chọn Accelerator và nhấp vào New.

Step 3 - Nhấp vào mũi tên của hộp tổ hợp ID và chọn menu Mục.

Step 4 - Chọn Ctrl từ menu thả xuống Modifier.

Step 5 - Nhấp vào ô Chìa khóa và nhập các Chìa khóa tương ứng cho cả hai tùy chọn menu.

Chúng tôi cũng sẽ thêm trình xử lý sự kiện mục menu mới để thử nghiệm. Nhấp chuột phải vào tùy chọn trình đơn Mới.

Step 6- Bạn có thể chỉ định một lớp, kiểu thông báo và tên trình xử lý. Bây giờ, chúng ta hãy để nó như vậy và nhấp vào nút Thêm và Chỉnh sửa.

Step 7 - Chọn Thêm Trình xử lý Sự kiện.

Step 8 - Bây giờ bạn sẽ thấy sự kiện được thêm vào cuối tệp CMFCModalDemoDlg.cpp.

void CMFCModalDemoDlg::OnFileNew() {
   // TODO: Add your command handler code here
   MessageBox(L"File > New menu option");
}

Step 9 - Now Hãy để chúng tôi thêm một hộp thông báo sẽ hiển thị thông báo tùy chọn menu đơn giản.

Để bắt đầu bảng tăng tốc hoạt động, hãy thêm biến HACCEL và ProcessMessageFilter như được hiển thị trong CMFCModalDemoApp sau.

class CMFCModalDemoApp : public CWinApp {
   public:
      CMFCModalDemoApp();
   
   // Overrides
   public:
      virtual BOOL InitInstance();
      HACCEL m_hAccelTable;
      
      // Implementation

      DECLARE_MESSAGE_MAP()
      virtual BOOL ProcessMessageFilter(int code, LPMSG lpMsg);
};

Step 10 - Tải Accelerator và cuộc gọi sau trong CMFCModalDemoApp :: InitInstance ().

m_hAccelTable = LoadAccelerators(AfxGetInstanceHandle(),
   MAKEINTRESOURCE(IDR_ACCELERATOR1));

Step 11 - Đây là phần thực hiện ProcessMessageFilter.

BOOL CMFCModalDemoApp::ProcessMessageFilter(int code, LPMSG lpMsg) {
   if (code >= 0 && m_pMainWnd && m_hAccelTable) {
      if (::TranslateAccelerator(m_pMainWnd -> m_hWnd, m_hAccelTable, lpMsg))
      return TRUE;
   }
   return CWinApp::ProcessMessageFilter(code, lpMsg);
}

Step 12 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 13 - Nhấn nút Alt sau đó là phím F rồi đến phím N hoặc Ctrl + N. Bạn sẽ thấy thông báo sau.

A property sheet, còn được gọi là hộp thoại tab, là một hộp thoại chứa các trang thuộc tính. Mỗi trang thuộc tính dựa trên tài nguyên mẫu hộp thoại và chứa các điều khiển. Nó được bao gồm trên một trang với một tab ở trên cùng. Tab đặt tên cho trang và cho biết mục đích của nó. Người dùng nhấp vào một tab trong trang thuộc tính để chọn một tập hợp các điều khiển.

Để tạo các trang thuộc tính, chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một dự án MFC dựa trên hộp thoại.

Khi dự án được tạo, chúng tôi cần thêm một số trang thuộc tính.

Visual Studio giúp dễ dàng tạo tài nguyên cho các trang thuộc tính bằng cách hiển thị hộp thoại Thêm tài nguyên, mở rộng nút Hộp thoại và chọn một trong các mục IDD_PROPPAGE_X.

Step 1 - Nhấp chuột phải vào dự án của bạn trong trình khám phá giải pháp và chọn Thêm → Tài nguyên.

Step 2 - Chọn IDD_PROPPAGE_LARGE và nhấp vào MỚI.

Step 3 - Hãy để chúng tôi thay đổi ID và Chú thích của trang thuộc tính này thành IDD_PROPPAGE_1Property Page 1 tương ứng như hình trên.

Step 4 - Nhấp chuột phải vào trang thuộc tính trong cửa sổ trình thiết kế.

Step 5 - Chọn tùy chọn Thêm Lớp.

Step 6 - Nhập tên lớp và chọn CPropertyPage từ danh sách thả xuống của lớp cơ sở.

Step 7 - Nhấn Hoàn tất để tiếp tục.

Step 8 - Thêm một trang thuộc tính khác với ID IDD_PROPPAGE_2 và Trang thuộc tính phụ đề 2 bằng cách làm theo các bước đã đề cập ở trên.

Step 9- Bây giờ bạn có thể thấy hai trang thuộc tính được tạo. Để triển khai chức năng của nó, chúng ta cần một bảng thuộc tính.

Bảng Thuộc tính nhóm các trang thuộc tính lại với nhau và giữ nó dưới dạng thực thể.

Để tạo trang thuộc tính, hãy làm theo các bước dưới đây:

Step 1 - Nhấp chuột phải vào dự án của bạn và chọn Tùy chọn menu Thêm> Lớp.

Step 2 - Chọn Visual C ++ → MFC từ ngăn bên trái và MFC Class trong ngăn mẫu và nhấp vào Thêm.

Step 3 - Nhập tên lớp và chọn CPropertySheet từ danh sách thả xuống của lớp cơ sở.

Step 4 - Bấm kết thúc để tiếp tục.

Step 5 - Để khởi chạy trang thuộc tính này, chúng ta cần những thay đổi sau trong lớp dự án chính của chúng ta.

Step 6 - Thêm các tham chiếu sau trong tệp CMFCPropSheetDemo.cpp.

#include "MySheet.h"
#include "PropPage1.h"
#include "PropPage2.h"

Step 7 - Sửa đổi phương thức CMFCPropSheetDemoApp :: InitInstance () như trong đoạn mã sau.

CMySheet mySheet(L"Property Sheet Demo");
CPropPage1 page1;
CPropPage2 page2;

mySheet.AddPage(&page1);
mySheet.AddPage(&page2);

m_pMainWnd = &mySheet;
INT_PTR nResponse = mySheet.DoModal();

Step 8 - Đây là phần triển khai hoàn chỉnh của tệp CMFCPropSheetDemo.cpp.

// MFCPropSheetDemo.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "MFCPropSheetDemo.h"
#include "MFCPropSheetDemoDlg.h"
#include "MySheet.h"
#include "PropPage1.h"
#include "PropPage2.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMFCPropSheetDemoApp
BEGIN_MESSAGE_MAP(CMFCPropSheetDemoApp, CWinApp)
   ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()


// CMFCPropSheetDemoApp construction

CMFCPropSheetDemoApp::CMFCPropSheetDemoApp() {

   // support Restart Manager
   m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
   // TODO: add construction code here,
   // Place all significant initialization in InitInstance
}


// The one and only CMFCPropSheetDemoApp object

CMFCPropSheetDemoApp theApp;


// CMFCPropSheetDemoApp initialization

BOOL CMFCPropSheetDemoApp::InitInstance() {
   
   // InitCommonControlsEx() is required on Windows XP if an application
   // manifest specifies use of ComCtl32.dll version 6 or later to enable
   // visual styles. Otherwise, any window creation will fail.
   INITCOMMONCONTROLSEX InitCtrls;
   InitCtrls.dwSize = sizeof(InitCtrls);
   // Set this to include all the common control classes you want to use
   // in your application.
   InitCtrls.dwICC = ICC_WIN95_CLASSES;
   InitCommonControlsEx(&InitCtrls);
   
   CWinApp::InitInstance();
   
   
   AfxEnableControlContainer();
   
   // Create the shell manager, in case the dialog contains
   // any shell tree view or shell list view controls.
   CShellManager *pShellManager = new CShellManager;

   // Activate "Windows Native" visual manager for enabling themes in MFC controls
   CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
   // Standard initialization
   // If you are not using these features and wish to reduce the size
   // of your final executable, you should remove from the following
   // the specific initialization routines you do not need
   // Change the registry key under which our settings are stored
   // TODO: You should modify this string to be something appropriate
   // such as the name of your company or organization
   SetRegistryKey(_T("Local AppWizard-Generated Applications"));
   
   CMySheet mySheet(L"Property Sheet Demo");
   CPropPage1 page1;
   CPropPage2 page2;
   
   mySheet.AddPage(&page1);
   mySheet.AddPage(&page2);
   
   m_pMainWnd = &mySheet;
   INT_PTR nResponse = mySheet.DoModal();
   if (nResponse == IDOK) {
      // TODO: Place code here to handle when the dialog is
      // dismissed with OK
   }else if (nResponse == IDCANCEL) {
      // TODO: Place code here to handle when the dialog is
      // dismissed with Cancel
   }else if (nResponse == -1) {    
      TRACE(traceAppMsg, 0, "Warning: dialog creation failed, 
        so application is terminating unexpectedly.\n");
      TRACE(traceAppMsg, 0, "Warning: if you are using MFC controls on the dialog, 
        you cannot #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS.\n");
   }

   // Delete the shell manager created above.
   if (pShellManager != NULL) {
      delete pShellManager;
   }

   // Since the dialog has been closed, return FALSE so that we exit the
   // application, rather than start the application's message pump.
   return FALSE;
}

Step 9- Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy hộp thoại sau. Hộp thoại này chứa hai trang thuộc tính.

Layout of controlsrất quan trọng và quan trọng đối với khả năng sử dụng ứng dụng. Nó được sử dụng để sắp xếp một nhóm các phần tử GUI trong ứng dụng của bạn. Có một số điều quan trọng cần xem xét khi chọn bố cục -

  • Vị trí của các phần tử con.
  • Kích thước của các phần tử con.

Thêm điều khiển

Hãy để chúng tôi tạo Dự án MFC dựa trên Hộp thoại MFCLayoutDemo mới.

Step 1 - Sau khi dự án được tạo, bạn sẽ thấy màn hình sau.

Step 2 - Xóa VIỆC CẦN LÀM khỏi hộp thoại.

Step 3 - Kéo một số điều khiển từ Hộp công cụ mà bạn có thể thấy ở phía bên trái.

(Chúng tôi sẽ kéo một Văn bản tĩnh và một Điều khiển chỉnh sửa như được hiển thị trong ảnh chụp nhanh sau đây).

Step 4 - Thay đổi Chú thích của Văn bản tĩnh thành Tên.

Lưới kiểm soát

Lưới điều khiển là các chấm lưới hướng dẫn, có thể giúp định vị các điều khiển bạn đang thêm vào lúc thiết kế.

Để kích hoạt lưới điều khiển, bạn cần nhấp vào nút Toggle Grid trên thanh công cụ như thể hiện trong ảnh chụp nhanh sau.

Kiểm soát thay đổi kích thước

Sau khi bạn đã thêm một điều khiển vào một hộp thoại, nó sẽ giả định kích thước mặc định của nó hoặc kích thước bạn đã vẽ. Để trợ giúp về kích thước của các điều khiển trên biểu mẫu hoặc hộp thoại, Visual Studio cung cấp một lưới trực quan làm bằng các điểm đen.

Để thay đổi kích thước điều khiển, nghĩa là, để cung cấp cho nó một chiều rộng hoặc chiều cao cụ thể, hãy đặt chuột vào một trong các tay cầm và kéo nó theo hướng mong muốn.

Bây giờ bạn có thể thay đổi kích thước của các điều khiển với sự trợ giúp của lưới chấm chấm này.

Kiểm soát vị trí

Các điều khiển mà bạn định vị trên hộp thoại hoặc biểu mẫu giả định vị trí nhất định của chúng. Hầu hết thời gian, những vị trí này không thực tế. Bạn có thể di chuyển chúng đến bất kỳ vị trí nào bạn chọn.

Hãy để chúng tôi thêm một số điều khiển khác -

Step 1 - Để di chuyển điều khiển, hãy nhấp và kéo điều khiển đó theo hướng mong muốn cho đến khi nó đến vị trí đã định.

Step 2- Để di chuyển một nhóm điều khiển, trước tiên hãy chọn chúng. Sau đó kéo lựa chọn đến vị trí mong muốn. Hãy để chúng tôi chọn Văn bản tĩnh và Điều khiển chỉnh sửa.

Step 3 - Di chuyển các điều khiển đã chọn này sang phía bên trái.

Để giúp định vị các điều khiển, Visual Studio cung cấp thanh công cụ Hộp thoại với các nút sau.

Step 1 - Chúng ta hãy căn chỉnh các điều khiển Hộp kiểm và Văn bản tĩnh ở bên trái bằng cách chọn tất cả các điều khiển này.

Step 2 - Chọn Định dạng → Căn chỉnh → Nâng.

Step 3 - Bây giờ bạn có thể thấy tất cả các điều khiển này được căn chỉnh ở bên trái.

Đặt hàng tab

Các điều khiển bạn thêm vào biểu mẫu hoặc hộp thoại được đặt theo trình tự theo thứ tự chúng được thêm vào. Khi bạn thêm (các) điều khiển bất kể phần hoặc khu vực bạn đặt điều khiển mới, nó sẽ được định vị tuần tự ở cuối các điều khiển hiện có. Nếu bạn không sửa nó, người dùng sẽ gặp khó khăn trong việc điều hướng các điều khiển. Trình tự điều hướng điều khiển còn được gọi là thứ tự tab.

Để thay đổi tab, bạn có thể sử dụng tùy chọn menu Định dạng → Thứ tự tab hoặc bạn cũng có thể sử dụng phím tắt Ctrl + D. Chúng ta hãy nhấn Ctrl + D.

Bây giờ bạn có thể thấy thứ tự mà tất cả các điều khiển này được thêm vào hộp thoại này. Để thay đổi thứ tự hoặc trình tự điều khiển, hãy nhấp vào tất cả các điều khiển theo thứ tự mà bạn muốn điều hướng.

Trong ví dụ này, trước tiên chúng ta sẽ nhấp vào hộp kiểm, tiếp theo là các điều khiển Chỉnh sửa Tên và Địa chỉ. Sau đó nhấp vào OK và Cancel như được hiển thị trong ảnh chụp nhanh sau đây.

Hãy để chúng tôi chạy ứng dụng này và bạn sẽ thấy kết quả sau.

Trong các ứng dụng MFC, sau khi thêm điều khiển vào ứng dụng của bạn một cách trực quan, nếu bạn muốn tham chiếu đến nó trong mã của mình, bạn có thể khai báo một biến dựa trên hoặc được liên kết với điều khiển đó. Thư viện MFC cho phép bạn khai báo hai loại biến cho một số điều khiển được sử dụng trong ứng dụng là một giá trị hoặc một biến điều khiển.

  • Một biến được sử dụng cho thông tin được lưu trữ trong điều khiển, còn được gọi là Control Variable/Instance.

  • Biến khác được gọi là Control Value Variable. Người dùng có thể thực hiện một số loại hành động trên điều khiển đó với biến này.

Kiểm soát biến / phiên bản

Biến điều khiển là một biến dựa trên lớp quản lý điều khiển. Ví dụ, một nút điều khiển dựa trên lớp CButton.

Để xem các khái niệm này trong lập trình thực, chúng ta hãy tạo một dự án MFCControlManagement dựa trên hộp thoại MFC.

Sau khi dự án được tạo, bạn sẽ thấy hộp thoại sau trong cửa sổ trình thiết kế.

Step 1- Xóa dòng TODO và kéo một hộp kiểm và một điều khiển Chỉnh sửa như thể hiện trong ảnh chụp nhanh sau. Thay đổi chú thích của hộp kiểm thành Bật điều khiển.

Step 2 - Nhấp chuột phải vào hộp kiểm.

Step 3 - Chọn Thêm biến.

Step 4 - Bây giờ bạn có thể xem Trình hướng dẫn thêm biến thành viên.

Bạn có thể chọn các tùy chọn khác nhau trên hộp thoại này. Đối với hộp kiểm, loại biến là CButton. Nó được chọn theo mặc định trong hộp thoại này.

Tương tự, ID điều khiển cũng được chọn theo mặc định, bây giờ chúng ta cần chọn Điều khiển trong hộp tổ hợp Danh mục và nhập m_enableDisableCheck vào hộp chỉnh sửa Tên biến và nhấp vào kết thúc.

Step 5 - Tương tự, thêm Control Variable của điều khiển Edit với các cài đặt như trong ảnh chụp sau.

Quan sát tệp tiêu đề của lớp hộp thoại. Bạn có thể thấy rằng các biến mới đã được thêm vào bây giờ.

CButton m_enableDisableCheck;
CEdit m_myEditControl;

Kiểm soát biến giá trị

Một loại biến khác mà bạn có thể khai báo cho một điều khiển là biến giá trị. Không phải tất cả các điều khiển đều cung cấp một biến giá trị.

  • Biến giá trị phải có khả năng xử lý kiểu giá trị được lưu trữ trong điều khiển mà nó dự định tham chiếu đến.

  • Ví dụ: vì một điều khiển dựa trên văn bản được sử dụng để xử lý văn bản, bạn có thể khai báo một kiểu dữ liệu dựa trên văn bản cho nó. Đây thường sẽ là một biến CString.

Hãy để chúng tôi xem xét loại biến này để kiểm soát hộp kiểm và chỉnh sửa.

Step 1 - Nhấp chuột phải vào hộp kiểm và chọn Thêm biến.

Step 2- Loại biến là BOOL. Chọn Giá trị từ danh sách thả xuống Danh mục.

Step 3 - Nhấn Hoàn tất để tiếp tục.

Step 4 - Tương tự, thêm giá trị Biến cho điều khiển Chỉnh sửa với các cài đặt như trong ảnh chụp sau.

Step 5 - Gõ CString vào kiểu biến và m_editControlVal trong trường tên biến.

Step 6 - Bây giờ bạn có thể thấy các biến này được thêm vào trong tệp Header.

bool m_enableDisableVal;
CString m_editControlVal;

Kiểm soát trình xử lý sự kiện

Sau khi thêm một điều khiển vào ứng dụng của bạn, cho dù bạn đã thêm trực quan hay tạo động, bạn cũng sẽ quyết định cách xử lý các tác vụ có thể mà người dùng có thể thực hiện trên điều khiển.

  • Đối với các hộp thoại dự án đã được liên kết với một lớp, bạn có thể tận dụng một số phím tắt khi tạo trình xử lý sự kiện.

  • Bạn có thể nhanh chóng tạo một trình xử lý cho sự kiện thông báo điều khiển mặc định hoặc cho bất kỳ thông báo Windows áp dụng nào.

Chúng ta hãy xem xét cùng một ví dụ mà chúng tôi đã thêm trình xử lý sự kiện cho hộp kiểm.

Step 1 - Nhấp chuột phải vào điều khiển mà bạn muốn xử lý sự kiện thông báo.

Step 2 - Trên menu lối tắt, bấm Thêm Trình xử lý Sự kiện để hiển thị Trình hướng dẫn Xử lý Sự kiện.

Step 3 - Chọn sự kiện trong hộp Loại tin nhắn để thêm vào lớp đã chọn trong hộp danh sách Lớp.

Step 4 - Chấp nhận tên mặc định trong hộp Tên trình xử lý hàm hoặc cung cấp tên bạn chọn.

Step 5 - Nhấp vào Thêm và chỉnh sửa để thêm trình xử lý sự kiện.

Step 6 - Bây giờ bạn có thể thấy sự kiện sau được thêm vào cuối tệp CMFCControlManagementDlg.cpp.

void CMFCControlManagementDlg::OnBnClickedCheck1() {
   // TODO: Add your control notification handler code here
}

Quản lý kiểm soát

Cho đến nay, chúng ta đã biết cách thêm các điều khiển vào một ứng dụng. Bây giờ chúng ta sẽ xem cách quản lý các điều khiển này theo yêu cầu của người dùng. Chúng ta có thể sử dụng biến / thể hiện điều khiển trong một trình xử lý sự kiện cụ thể.

Step 1- Chúng ta hãy xem xét ví dụ sau. Tại đây, chúng tôi sẽ bật / tắt kiểm soát chỉnh sửa khi hộp kiểm được chọn / bỏ chọn.

Step 2- Bây giờ chúng tôi đã thêm trình xử lý sự kiện nhấp vào hộp kiểm. Đây là cách thực hiện -

void CMFCControlManagementDlg::OnBnClickedCheck1() {
   // TODO: Add your control notification handler code here
   UpdateData(TRUE);
   if (m_enableDisableVal)
      m_myEditControl.EnableWindow(TRUE);
   else
      m_myEditControl.EnableWindow(FALSE);
}

Step 3- Khi hộp thoại được tạo, chúng ta cần thêm đoạn mã sau vào CMFCControlManagementDlg :: OnInitDialog (). Điều này sẽ quản lý các điều khiển này.

UpdateData(TRUE);
if (m_enableDisableVal)
   m_myEditControl.EnableWindow(TRUE);
else
   m_myEditControl.EnableWindow(FALSE);

Step 4 - Đây là phần triển khai hoàn chỉnh của tệp CMFCControlManagementDlg.cpp.

// MFCControlManagementDlg.cpp : implementation file
//

#include "stdafx.h"
#include "MFCControlManagement.h"
#include "MFCControlManagementDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CAboutDlg dialog used for App About

class CAboutDlg : public CDialogEx {
   public:
      CAboutDlg();
	
   // Dialog Data
   #ifdef AFX_DESIGN_TIME
      enum { IDD = IDD_ABOUTBOX };
   #endif

   protected:
      virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
      
   // Implementation
   protected:
      DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX) {

}
void CAboutDlg::DoDataExchange(CDataExchange* pDX) {
   CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()

// CMFCControlManagementDlg dialog


CMFCControlManagementDlg::CMFCControlManagementDlg(CWnd* pParent /* = NULL*/)
   :CDialogEx(IDD_MFCCONTROLMANAGEMENT_DIALOG, pParent) , 
   m_enableDisableVal(FALSE) , m_editControlVal(_T("")) {
   m_hIcon = AfxGetApp()&rarr LoadIcon(IDR_MAINFRAME);
}

void CMFCControlManagementDlg::DoDataExchange(CDataExchange* pDX) {
   CDialogEx::DoDataExchange(pDX);
   DDX_Control(pDX, IDC_CHECK1, m_enableDisableCheck);
   DDX_Control(pDX, IDC_EDIT1, m_myEditControl);
   DDX_Check(pDX, IDC_CHECK1, m_enableDisableVal);
   DDX_Text(pDX, IDC_EDIT1, m_editControlVal);
}
BEGIN_MESSAGE_MAP(CMFCControlManagementDlg, CDialogEx)
   ON_WM_SYSCOMMAND()
   ON_WM_PAINT()
   ON_WM_QUERYDRAGICON()
   ON_BN_CLICKED(IDC_CHECK1, &CMFCControlManagementDlg::OnBnClickedCheck1)
END_MESSAGE_MAP()

// CMFCControlManagementDlg message handlers

BOOL CMFCControlManagementDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();
      
   // Add "About..." menu item to system menu.
   // IDM_ABOUTBOX must be in the system command range.
   ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
   ASSERT(IDM_ABOUTBOX < 0xF000);
      
   CMenu* pSysMenu = GetSystemMenu(FALSE);
   if (pSysMenu != NULL) {
      BOOL bNameValid;
      CString strAboutMenu;
      bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
      ASSERT(bNameValid);
      if (!strAboutMenu.IsEmpty()) {
         pSysMenu → AppendMenu(MF_SEPARATOR);
         pSysMenu → AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
      }
   }
	
   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);        // Set big icon
   SetIcon(m_hIcon, FALSE);       // Set small icon

   // TODO: Add extra initialization here
   UpdateData(TRUE);
   if (m_enableDisableVal)
      m_myEditControl.EnableWindow(TRUE);
   else
      m_myEditControl.EnableWindow(FALSE);
   return TRUE; // return TRUE unless you set the focus to a control
}
void CMFCControlManagementDlg::OnSysCommand(UINT nID, LPARAM lParam) {
   if ((nID & 0xFFF0) == IDM_ABOUTBOX) {
      CAboutDlg dlgAbout;
      dlgAbout.DoModal();
   }else {
      CDialogEx::OnSysCommand(nID, lParam);
   }
}

// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.

void CMFCControlManagementDlg::OnPaint() {
   if (IsIconic()) {
      CPaintDC dc(this); // device context for painting
      
      SendMessage(WM_ICONERASEBKGND,
         reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
			
      // Center icon in client rectangle
      int cxIcon = GetSystemMetrics(SM_CXICON);
      int cyIcon = GetSystemMetrics(SM_CYICON);
      CRect rect;
      GetClientRect(&rect);
      int x = (rect.Width() - cxIcon + 1) / 2;
      int y = (rect.Height() - cyIcon + 1) / 2;
		
      // Draw the icon
      dc.DrawIcon(x, y, m_hIcon);
   }else {
      CDialogEx::OnPaint();
   }
}

// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMFCControlManagementDlg::OnQueryDragIcon() {
   return static_cast<HCURSOR>(m_hIcon);
}

void CMFCControlManagementDlg::OnBnClickedCheck1() {
   // TODO: Add your control notification handler code here
   UpdateData(TRUE);
   if (m_enableDisableVal)
      m_myEditControl.EnableWindow(TRUE);
   else
      m_myEditControl.EnableWindow(FALSE);
}

Step 5- Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau. Hộp kiểm được bỏ chọn theo mặc định. Điều này cũng vô hiệu hóa kiểm soát chỉnh sửa.

Step 6- Đánh dấu vào hộp kiểm Enable Control. Điều này sẽ tự động bật kiểm soát chỉnh sửa.

Windows controlslà các đối tượng mà người dùng có thể tương tác để nhập hoặc thao tác dữ liệu. Chúng thường xuất hiện trong hộp thoại hoặc trên thanh công cụ. Có nhiều loại điều khiển -

  • A text based control được sử dụng để hiển thị văn bản cho người dùng hoặc yêu cầu văn bản từ người dùng.

  • A list based control hiển thị danh sách các mục.

  • A progress based control được sử dụng để hiển thị tiến trình của một hành động.

  • A static control có thể được sử dụng để hiển thị màu sắc, một bức tranh hoặc một cái gì đó không thường xuyên phù hợp với các loại trên.

Sr.No. Điều khiển & Mô tả
1 Kiểm soát tĩnh

Điều khiển tĩnh là một đối tượng hiển thị thông tin cho người dùng mà không có sự can thiệp trực tiếp của họ. Nó có thể được sử dụng để hiển thị màu sắc, hình dạng hình học hoặc hình ảnh như biểu tượng, ảnh bitmap hoặc hoạt ảnh.

2 Kiểm soát hoạt ảnh

Điều khiển hoạt ảnh là một cửa sổ hiển thị đoạn âm thanh ở định dạng AVI. Clip AVI là một chuỗi các khung hình bitmap, giống như một bộ phim. Các điều khiển hoạt ảnh chỉ có thể phát các clip AVI đơn giản và chúng không hỗ trợ âm thanh. Nó được đại diện bởiCAnimateCtrl lớp học.

3 Cái nút

A buttonlà một đối tượng mà người dùng nhấp vào để bắt đầu một hành động. Điều khiển nút được đại diện bởiCButton class.

4 Nút bitmap

A bitmap buttonhiển thị hình ảnh hoặc hình ảnh và văn bản trên mặt của nó. Điều này thường nhằm mục đích làm cho nút rõ ràng một chút. Một nút bitmap được tạo bằng cách sử dụngCBitmapButton class, có nguồn gốc từ CButton.

5 Nút lệnh

A command buttonlà phiên bản nâng cao của nút thông thường. Nó hiển thị biểu tượng mũi tên màu xanh lá cây ở bên trái, theo sau là chú thích ở kích thước thông thường. Dưới chú thích chính, nó có thể hiển thị một chú thích khác nhỏ hơn đóng vai trò như một gợi ý để cung cấp thêm thông tin.

6 Văn bản tĩnh

A static controlhiển thị một chuỗi văn bản, hộp, hình chữ nhật, biểu tượng, con trỏ, bitmap hoặc siêu tệp nâng cao. Nó được đại diện bởiCStatic class. Nó có thể được sử dụng để dán nhãn, đóng hộp hoặc tách các điều khiển khác. Một điều khiển tĩnh thường không có đầu vào và không cung cấp đầu ra.

7 Hộp danh sách

A list boxhiển thị danh sách các mục, chẳng hạn như tên tệp, mà người dùng có thể xem và chọn. Hộp Danh sách được đại diện bởiCListBox class. Trong một hộp danh sách lựa chọn duy nhất, người dùng chỉ có thể chọn một mục. Trong hộp danh sách nhiều lựa chọn, có thể chọn một loạt các mục. Khi người dùng chọn một mục, mục đó sẽ được tô sáng và hộp danh sách sẽ gửi tin nhắn thông báo đến cửa sổ mẹ.

số 8 Hộp kết hợp

A combo boxbao gồm một hộp danh sách kết hợp với một điều khiển tĩnh hoặc điều khiển chỉnh sửa. nó được đại diện bởiCComboBox class. Phần hộp danh sách của điều khiển có thể được hiển thị mọi lúc hoặc chỉ có thể thả xuống khi người dùng chọn mũi tên thả xuống bên cạnh điều khiển.

9 Các nút radio

A radio buttonlà một điều khiển xuất hiện dưới dạng một dấu chấm được bao quanh bởi một hộp tròn. Trên thực tế, một nút radio đi kèm với một hoặc nhiều nút radio khác xuất hiện và hoạt động như một nhóm.

10 Hộp kiểm

Hộp kiểm là một điều khiển Windows cho phép người dùng đặt hoặc thay đổi giá trị của một mục là đúng hoặc sai.

11 Danh sách hình ảnh

An Image Listlà một tập hợp các hình ảnh có cùng kích thước, mỗi hình ảnh có thể được tham chiếu bằng chỉ mục dựa trên số không của nó. Danh sách hình ảnh được sử dụng để quản lý hiệu quả các bộ biểu tượng hoặc bitmap lớn. Danh sách hình ảnh được đại diện bởiCImageList class.

12 Hộp chỉnh sửa

An Edit Boxlà một cửa sổ con hình chữ nhật trong đó người dùng có thể nhập văn bản. Nó được đại diện bởiCEdit class.

13 Chỉnh sửa phong phú

A Rich EditControl là một cửa sổ trong đó người dùng có thể nhập và chỉnh sửa văn bản. Văn bản có thể được gán định dạng ký tự và đoạn văn, và có thể bao gồm các đối tượng OLE được nhúng. Nó được đại diện bởiCRichEditCtrl class.

14 Hộp nhóm

A group boxlà một điều khiển tĩnh được sử dụng để đặt một nhóm điều khiển hiển thị hoặc có lập trình. Điều khiển là một hình chữ nhật nhóm các điều khiển khác lại với nhau.

15 Nút quay

A Spin ButtonĐiều khiển (còn được gọi là điều khiển lên xuống) là một cặp nút mũi tên mà người dùng có thể nhấp để tăng hoặc giảm một giá trị, chẳng hạn như vị trí cuộn hoặc một số được hiển thị trong điều khiển đồng hành. nó được đại diện bởiCSpinButtonCtrl class.

16 Quản lý Kiểm soát Cập nhật

Nó quản lý các điều khiển cập nhật.

17 Kiểm soát tiến độ

A progress bar controllà một cửa sổ mà ứng dụng có thể sử dụng để chỉ ra tiến trình của một hoạt động kéo dài. Nó bao gồm một hình chữ nhật được tô dần, từ trái sang phải, với màu đánh dấu của hệ thống khi một hoạt động diễn ra. Nó được đại diện bởiCProgressCtrl class.

18 Thanh tiến trình

A progress bars là một cửa sổ mà ứng dụng có thể sử dụng để chỉ ra tiến trình của một hoạt động.

19 Hẹn giờ

A timerlà một đối tượng phi không gian sử dụng khoảng thời gian lặp lại từ máy tính hoặc ứng dụng của bạn. Để hoạt động, mỗi khoảng thời gian trôi đi, điều khiển sẽ gửi một thông báo đến hệ điều hành. Không giống như hầu hết các điều khiển khác, bộ đếm thời gian MFC không có nút để đại diện cho nó cũng như một lớp. Để tạo bộ đếm thời gian, bạn chỉ cần gọi phương thức CWnd :: SetTimer (). Lệnh gọi hàm này tạo ra một bộ đếm thời gian cho ứng dụng của bạn. Giống như các điều khiển khác, bộ hẹn giờ sử dụng một số nhận dạng.

20 Bộ chọn ngày & giờ

Kiểm soát bộ chọn ngày và giờ (CDateTimeCtrl) thực hiện một phương pháp nhập hoặc chọn một ngày cụ thể trực quan và dễ nhận biết. Giao diện chính của điều khiển có chức năng tương tự như hộp tổ hợp. Tuy nhiên, nếu người dùng mở rộng điều khiển, điều khiển lịch tháng sẽ xuất hiện (theo mặc định), cho phép người dùng chỉ định một ngày cụ thể. Khi một ngày được chọn, điều khiển lịch tháng sẽ tự động biến mất.

21 Hình ảnh

Nếu bạn cần hiển thị hình ảnh cho ứng dụng của mình, Visual C ++ cung cấp một điều khiển đặc biệt cho mục đích đó.

22 Biên tập hình ảnh

Các Image editorcó một bộ công cụ mở rộng để tạo và chỉnh sửa hình ảnh, cũng như các tính năng để giúp bạn tạo bản đồ bit trên thanh công cụ. Ngoài bitmap, biểu tượng và con trỏ, bạn có thể chỉnh sửa hình ảnh ở định dạng GIF hoặc JPEG bằng cách sử dụng các lệnh trên menu Hình ảnh và các công cụ trên Thanh công cụ Trình chỉnh sửa Hình ảnh.

23 Điều khiển thanh trượt

A Slider Control(còn được gọi là trackbar) là một cửa sổ chứa thanh trượt và các dấu tích tùy chọn. Khi người dùng di chuyển thanh trượt, sử dụng chuột hoặc các phím điều hướng, điều khiển sẽ gửi tin nhắn thông báo để cho biết sự thay đổi. Có hai loại thanh trượt - ngang và dọc. Nó được đại diện bởiCSliderCtrl class.

24 Thanh cuộn

A scrollbarlà phần tử điều khiển đồ họa mà văn bản liên tục, hình ảnh hoặc bất kỳ thứ gì khác có thể được cuộn theo hai hướng dọc theo điều khiển bằng cách nhấp vào mũi tên. Điều khiển này có thể giả định một trong hai hướng - ngang hoặc dọc. Nó được đại diện bởiCScrollBar lớp học.

25 Kiểm soát cây

A Tree View Controllà một cửa sổ hiển thị danh sách phân cấp các mục, chẳng hạn như các tiêu đề trong tài liệu, các mục nhập trong chỉ mục hoặc các tệp và thư mục trên đĩa. Mỗi mục bao gồm một nhãn và một hình ảnh được ánh xạ bit tùy chọn và mỗi mục có thể có một danh sách các subitem được liên kết với nó. Bằng cách nhấp vào một mục, người dùng có thể mở rộng và thu gọn danh sách các tiểu mục được liên kết. Nó được đại diện bởiCTreeCtrl lớp học.

26 Kiểm soát danh sách

Đóng gói chức năng của Điều khiển dạng xem danh sách, hiển thị một tập hợp các mục, mỗi mục bao gồm một biểu tượng (từ danh sách hình ảnh) và một nhãn. Nó được đại diện bởiCListCtrllớp học. Điều khiển danh sách bao gồm việc sử dụng một trong bốn dạng xem để hiển thị danh sách các mục.

Một ứng dụng được tạo từ các đối tượng khác nhau. Hầu hết thời gian, nhiều ứng dụng đang chạy trên máy tính và hệ điều hành liên tục được yêu cầu thực hiện một số nhiệm vụ. Bởi vì có thể có rất nhiều yêu cầu được đưa ra một cách không thể đoán trước, hệ điều hành để cho các đối tượng xác định những gì họ muốn, khi nào họ muốn và hành vi hoặc kết quả mà họ mong đợi.

Tổng quat

  • Hệ điều hành Microsoft Windows không thể dự đoán những loại yêu cầu mà một đối tượng sẽ cần được thực hiện và loại gán cho đối tượng khác sẽ cần.

  • Để quản lý tất cả các nhiệm vụ và yêu cầu này, các đối tượng gửi tin nhắn.

  • Mỗi đối tượng có trách nhiệm quyết định gửi thông điệp gì và gửi khi nào.

  • Để gửi một tin nhắn, một điều khiển phải tạo một sự kiện.

  • Để phân biệt giữa hai điều này, tên của thông báo thường bắt đầu bằng WM_ viết tắt của Window Message.

  • Tên của một sự kiện thường bắt đầu bằng Bật biểu thị một hành động.

  • Sự kiện là hành động gửi tin nhắn.

Bản đồ tin nhắn

Vì Windows là hệ điều hành hướng thông điệp, phần lớn lập trình cho môi trường Windows liên quan đến việc xử lý thông báo. Mỗi khi một sự kiện như gõ phím hoặc nhấp chuột xảy ra, một thông báo sẽ được gửi đến ứng dụng, sau đó ứng dụng phải xử lý sự kiện đó.

  • Để trình biên dịch quản lý thông báo, chúng nên được đưa vào định nghĩa lớp.

  • Các DECLARE_MESSAGE_MAP macro nên được cung cấp ở cuối định nghĩa lớp như được hiển thị trong đoạn mã sau.

class CMainFrame : public CFrameWnd {
   public:
      CMainFrame();
   protected:
      DECLARE_MESSAGE_MAP()
};
  • Các tin nhắn thực tế sẽ được liệt kê ngay phía trên dòng DECLARE_MESSAGE_MAP.

  • Để triển khai các thông báo, bạn cần tạo một bảng các thông báo mà chương trình của bạn đang sử dụng.

  • Bảng này sử dụng hai macro phân tách;

  • Nó bắt đầu bằng một BEGIN_MESSAGE_MAP và kết thúc bằng một END_MESSAGE_MAP macro.

  • Macro BEGIN_MESSAGE_MAP nhận hai đối số, tên lớp của bạn và lớp MFC mà bạn lấy từ lớp của mình như được hiển thị trong đoạn mã sau.

#include <afxwin.h>
class CMainFrame : public CFrameWnd {
   public:
      CMainFrame();
   protected:
      DECLARE_MESSAGE_MAP()
};
CMainFrame::CMainFrame() {

   // Create the window's frame
   Create(NULL, L"MFC Messages Demo", WS_OVERLAPPEDWINDOW,
                                      CRect(120, 100, 700, 480), NULL);
}
class CMessagesApp : public CWinApp {
   public:
      BOOL InitInstance();
};
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
END_MESSAGE_MAP()
BOOL CMessagesApp::InitInstance(){
   m_pMainWnd = new CMainFrame;
   m_pMainWnd->ShowWindow(SW_SHOW);
   m_pMainWnd->UpdateWindow();
   return TRUE;
}
CMessagesApp theApp;

Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một dự án Win32 mới.

Step 1 - Để tạo một dự án MFC, nhấp chuột phải vào dự án và chọn Thuộc tính.

Step 2 - Ở phần bên trái, nhấp vào Thuộc tính cấu hình → Chung.

Step 3 - Chọn tùy chọn 'Use MFC in Shared DLL' trong phần Project Defaults và nhấp vào OK.

Step 4 - Chúng ta cần thêm một tệp nguồn mới.

Step 5 - Nhấp chuột phải vào Dự án của bạn và chọn Thêm → Mục mới.

Step 6 - Trong phần Mẫu, nhấp vào Tệp C ++ (.cpp).

Step 7 - Bấm Thêm để Tiếp tục.

Step 8 - Bây giờ, thêm đoạn mã sau vào tệp * .cpp.

#include <afxwin.h>
class CMainFrame : public CFrameWnd {
   public:
      CMainFrame();
   protected:
      DECLARE_MESSAGE_MAP()
};

CMainFrame::CMainFrame() {
   // Create the window's frame
   Create(NULL, L"MFC Messages Demo", WS_OVERLAPPEDWINDOW,
      CRect(120, 100, 700, 480), NULL);
}

class CMessagesApp : public CWinApp {
   public:
      BOOL InitInstance();
};

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
END_MESSAGE_MAP()
BOOL CMessagesApp::InitInstance() {
   m_pMainWnd = new CMainFrame;
   m_pMainWnd->ShowWindow(SW_SHOW);
   m_pMainWnd->UpdateWindow();
   return TRUE;
}
CMessagesApp theApp;

Tin nhắn Windows

Có nhiều loại thông báo Windows khác nhau như tạo cửa sổ, hiển thị cửa sổ, v.v. Dưới đây là một số thông báo Windows thường được sử dụng.

Thông điệp Mục nhập bản đồ Sự miêu tả
WM_ACTIVATE ON_WM_ACTIVATE () Khuôn khổ gọi hàm thành viên này khi một đối tượng CWnd đang được kích hoạt hoặc hủy kích hoạt.
WM_ACTIVATEA PP ON_WM_ACTIVATEAPP () Khuôn khổ gọi chức năng thành viên này cho tất cả các cửa sổ cấp cao nhất của tác vụ đang được kích hoạt và cho tất cả các cửa sổ cấp cao nhất của tác vụ đang được hủy kích hoạt.
WM_APPCOMM VÀ ON_WM_APPCOMMAND () Khuôn khổ gọi hàm thành viên này khi người dùng tạo một sự kiện lệnh ứng dụng.
WM_CANCELMODE WM_CANCELMODE () Khuôn khổ gọi chức năng thành viên này để thông báo cho CWnd hủy bất kỳ chế độ nội bộ nào.
WM_CHILDACTIVATE ON_WM_CHILDACTIVATE () Nếu đối tượng CWnd là một cửa sổ con của giao diện nhiều tài liệu (MDI), OnChildActivate được gọi bởi khung khi người dùng nhấp vào thanh tiêu đề của cửa sổ hoặc khi cửa sổ được kích hoạt, di chuyển hoặc định kích thước.
WM_CLIPBOAR DUPDATE ON_WM_CLIPBOARDUPDATE () Khuôn khổ gọi hàm thành viên này khi nội dung của khay nhớ tạm đã thay đổi.
WM_CLOSE ON_WM_CLOSE () Khuôn khổ gọi chức năng thành viên này như một tín hiệu rằng CWnd hoặc một ứng dụng sẽ kết thúc.
WM_CONTEXTMENU ON_WM_CONTEXTMENU () Được gọi bởi khuôn khổ khi người dùng đã nhấp vào nút chuột phải (nhấp chuột phải) trong cửa sổ.
WM_COPYDATA ON_WM_COPYDATA () Chức năng thành viên này được gọi bởi khuôn khổ để sao chép dữ liệu từ ứng dụng này sang ứng dụng khác.
WM_CREATE ON_WM_CREATE () Khuôn khổ gọi hàm thành viên này khi một ứng dụng yêu cầu tạo cửa sổ Windows bằng cách gọi hàm thành viên Create hoặc CreateEx.
WM_CTLCOLOR ON_WM_CTLCOLOR () Khung này gọi hàm thành viên này khi một điều khiển con sắp được vẽ.
WM_DELETEITEM ON_WM_DELETEITEM () Khuôn khổ gọi hàm thành viên này để thông báo cho chủ sở hữu của một hộp danh sách hoặc hộp tổ hợp kéo chủ sở hữu rằng hộp danh sách hoặc hộp tổ hợp đã bị phá hủy hoặc các mục đã bị loại bỏ.
WM_DESTROY ON_WM_DESTROY () anh ta gọi hàm thành viên này để thông báo cho đối tượng CWnd rằng nó đang bị phá hủy.
WM_DRAWITEM ON_WM_DRAWITEM () Khuôn khổ gọi chức năng thành viên này cho chủ sở hữu của điều khiển nút kéo chủ sở hữu, điều khiển hộp tổ hợp, điều khiển hộp danh sách hoặc menu khi khía cạnh trực quan của điều khiển hoặc menu đã thay đổi.
WM_DROPFILES ON_WM_DROPFILES () Khuôn khổ gọi chức năng thành viên này khi người dùng thả chuột trái qua cửa sổ đã đăng ký chính nó là người nhận các tệp bị đánh rơi.
WM_ENABLE ON_WM_ENABLE () Khuôn khổ gọi hàm thành viên này khi một ứng dụng thay đổi trạng thái được kích hoạt của đối tượng CWnd. Cú pháp.
WM_HELPINFO ON_WM_HELPINFO () Xử lý Trợ giúp F1 trong ứng dụng (sử dụng ngữ cảnh hiện tại).
WM_HOTKEY ON_WM_HOTKEY () Khung gọi chức năng thành viên này khi người dùng nhấn phím nóng trên toàn hệ thống.
WM_HSCROLL ON_WM_HSCROLL () Khung này gọi hàm thành viên này khi người dùng nhấp vào thanh cuộn ngang của cửa sổ.
WM_KEYDOWN ON_WM_KEYDOWN () Khuôn khổ gọi chức năng thành viên này khi một phím không hệ thống được nhấn.
WM_KEYUP ON_WM_KEYUP () Khuôn khổ gọi chức năng thành viên này khi một khóa nonsystem được phát hành.
WM_KILLFOCUS ON_WM_KILLFOCUS () Khuôn khổ gọi chức năng thành viên này ngay lập tức trước khi mất tiêu điểm đầu vào.
WM_LBUTTONDBLCLK ON_WM_LBUTTONDBLCLK () Khuôn khổ gọi chức năng thành viên này khi người dùng nhấp đúp chuột trái.
WM_LBUTTONDOWN ON_WM_LBUTTONDOWN () Khung gọi chức năng thành viên này khi người dùng nhấn nút trái chuột.
WM_LBUTTONUP ON_WM_LBUTTONUP () Khuôn khổ gọi chức năng thành viên này khi người dùng thả chuột trái.
WM_MBUTTONDBLCLK ON_WM_MBUTTONDBLCLK () Khung này gọi hàm thành viên này khi người dùng nhấp đúp chuột giữa.
WM_MBUTTONDOWN ON_WM_MBUTTONDOWN () Khung gọi chức năng thành viên này khi người dùng nhấn nút chuột giữa.
WM_MBUTTONUP ON_WM_MBUTTONUP () Khuôn khổ gọi chức năng thành viên này khi người dùng thả chuột giữa.
WM_MENUSELECT ON_WM_MENUSELECT () Nếu đối tượng CWnd được liên kết với một menu, OnMenuSelect được gọi bởi khuôn khổ khi người dùng chọn một mục menu.
WM_MOUSEACTIVATE ON_WM_MOUSEACTIVATE () Khung này gọi hàm thành viên này khi con trỏ ở trong cửa sổ không hoạt động và người dùng nhấn nút chuột.
WM_MOUSEHOVER ON_WM_MOUSEHOVER () Khuôn khổ gọi hàm thành viên này khi con trỏ di chuột qua vùng máy khách của cửa sổ trong khoảng thời gian được chỉ định trong lần gọi trước tới TrackMouseEvent.
WM_MOUSEHWHEEL ON_WM_MOUSEHWHEEL () Khuôn khổ gọi thành viên này khi cửa sổ hiện tại được tạo bởi Trình quản lý cửa sổ màn hình (DWM) và cửa sổ đó được phóng to.
WM_MOUSELEAVE ON_WM_MOUSELEAVE () Khuôn khổ gọi hàm thành viên này khi con trỏ rời khỏi vùng máy khách của cửa sổ được chỉ định trong lần gọi trước tới TrackMouseEvent.
WM_MOUSEMOVE ON_WM_MOUSEMOVE () Khung này gọi hàm thành viên này khi con trỏ chuột di chuyển.
WM_MOVE ON_WM_MOVE () Khuôn khổ gọi hàm thành viên này sau khi đối tượng CWnd đã được di chuyển.
WM_PAINT ON_WM_PAINT () Khung gọi hàm thành viên này khi Windows hoặc một ứng dụng đưa ra yêu cầu sơn lại một phần cửa sổ của ứng dụng.
WM_SETFOCUS () ON_WM_SETFOCUS () Khung này gọi hàm thành viên này sau khi đạt được tiêu điểm đầu vào.
WM_SIZE () ON_WM_SIZE () Khuôn khổ gọi hàm thành viên này sau khi kích thước của cửa sổ đã thay đổi.
WM_TIMER ON_WM_TIMER () Khuôn khổ gọi hàm thành viên này sau mỗi khoảng thời gian được chỉ định trong hàm thành viên SetTimer được sử dụng để cài đặt bộ đếm thời gian.
WM_VSCROLL ON_WM_VSCROLL () Khung này gọi hàm thành viên này khi người dùng nhấp vào thanh cuộn dọc của cửa sổ.
WM_WINDOWPOSCHANGED ON_WM_WINDOWPOSCHANGED () Khuôn khổ gọi hàm thành viên này khi kích thước, vị trí hoặc thứ tự Z đã thay đổi do lệnh gọi hàm thành viên SetWindowPos hoặc một hàm quản lý cửa sổ khác.

Chúng ta hãy xem xét một ví dụ đơn giản về tạo cửa sổ.

WM_CREATE - Khi một đối tượng, được gọi là cửa sổ, được tạo, khung tạo các đối tượng sẽ gửi một thông báo được xác định là ON_WM_CREATE.

Step 1- Để tạo ON_WM_CREATE, hãy thêm afx_msg int OnCreate (LPCREATESTRUCT lpCreateStruct); trước DECLARE_MESSAGE_MAP () như hình dưới đây.

class CMainFrame : public CFrameWnd {
   public:
      CMainFrame();
   protected:
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
      DECLARE_MESSAGE_MAP()
};

Step 2 - Thêm ON_WM_CREATE () sau BEGIN_MESSAGE_MAP (CMainFrame, CFrameWnd) và trước END_MESSAGE_MAP ()

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
   ON_WM_CREATE()
END_MESSAGE_MAP()

Step 3 - Đây là việc triển khai OnCreate ()

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
   // Call the base class to create the window
   if (CFrameWnd::OnCreate(lpCreateStruct) == 0) {

      // If the window was successfully created, let the user know
      MessageBox(L"The window has been created!!!");
      // Since the window was successfully created, return 0
      return 0;
   }
   // Otherwise, return -1
   return -1;
}

Step 4 - Bây giờ tệp * .cpp của bạn sẽ giống như trong đoạn mã sau.

#include <afxwin.h>
class CMainFrame : public CFrameWnd {
   public:
      CMainFrame();
   protected:
      afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
      DECLARE_MESSAGE_MAP()
};
CMainFrame::CMainFrame() {

   // Create the window's frame
   Create(NULL, L"MFC Messages Demo", WS_OVERLAPPEDWINDOW,
      CRect(120, 100, 700, 480), NULL);
}
class CMessagesApp : public CWinApp {
   public:
      BOOL InitInstance();
};
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
   ON_WM_CREATE()
END_MESSAGE_MAP()
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
   // Call the base class to create the window
   if (CFrameWnd::OnCreate(lpCreateStruct) == 0) {
      // If the window was successfully created, let the user know
      MessageBox(L"The window has been created!!!");
      // Since the window was successfully created, return 0
      return 0;
   }
   // Otherwise, return -1
   return -1;
}
BOOL CMessagesApp::InitInstance() { 
   m_pMainWnd = new CMainFrame;
   m_pMainWnd -> ShowWindow(SW_SHOW);
   m_pMainWnd -> UpdateWindow();
   return TRUE;
}
CMessagesApp theApp;

Step 5 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 6 - Khi bạn bấm OK, nó sẽ hiển thị cửa sổ chính.

Thông báo lệnh

Một trong những tính năng chính của ứng dụng đồ họa là trình bày các điều khiển và tài nguyên Windows cho phép người dùng tương tác với máy. Ví dụ về các điều khiển mà chúng ta sẽ học là các nút, hộp danh sách, hộp tổ hợp, v.v.

Một loại tài nguyên mà chúng tôi đã giới thiệu trong bài trước là menu. Các điều khiển và tài nguyên như vậy có thể khởi tạo thông báo của riêng chúng khi người dùng nhấp vào chúng. Thông báo phát ra từ điều khiển Windows hoặc tài nguyên được gọi là thông báo lệnh.

Chúng ta hãy xem xét một ví dụ đơn giản về thông điệp Lệnh.

Để cung cấp cho ứng dụng của bạn khả năng tạo một tài liệu mới, lớp CWinApp cung cấp phương thức OnFileNew ().

afx_msg void OnFileNew();

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
   ON_COMMAND(ID_FILE_NEW, CMainFrame::OnFileNew)
END_MESSAGE_MAP()

Đây là định nghĩa phương pháp -

void CMainFrame::OnFileNew() {
   // Create New file
}

Tin nhắn bàn phím

A keyboardlà một đối tượng phần cứng gắn liền với máy tính. Theo mặc định, nó được sử dụng để nhập các ký hiệu, chữ cái và các ký tự khác có thể nhận biết được trên một điều khiển. Mỗi phím trên bàn phím hiển thị một ký hiệu, một chữ cái hoặc kết hợp của các phím đó, để cho biết phím đó có thể được sử dụng để làm gì. Người dùng thường nhấn một phím để gửi tín hiệu đến một chương trình.

Mỗi khóa có một mã mà hệ điều hành có thể nhận ra. Mã này được gọi làvirtual key code.

Sr.No. Hằng số / giá trị & Mô tả
1

VK_LBUTTON

Nút chuột trái

2

VK_RBUTTON

Nút chuột phải

3

VK_CANCEL

Xử lý ngắt kiểm soát

4

VK_MBUTTON

Nút chuột giữa (chuột ba nút)

5

VK_BACK

Phím xóa

6

VK_RETURN

Phím ENTER

7

VK_TAB

Phím Tab

số 8

VK_CLEAR

Phím xóa

9

VK_SHIFT

Phím Shift

10

VK_CONTROL

Phím CTRL

11

VK_MENU

Phím ALT

12

VK_PAUSE

Phím PAUSE

13

VK_CAPITAL

Phím CAPS LOCK

14

VK_ESCAPE

Khóa ESC

15

VK_SPACE

Phím cách

16

VK_PRIOR

Phím TRANG LÊN

17

VK_NEXT

Phím TRANG XUỐNG

18

VK_END

Phím KẾT THÚC

19

VK_HOME

Chìa khóa nhà

20

VK_LEFT

Phím MŨI TÊN TRÁI

21

VK_UP

Phím mũi tên chỉ lên

22

VK_RIGHT

Phím MŨI TÊN PHẢI

23

VK_DOWN

Phím MŨI TÊN XUỐNG

24

VK_SELECT

CHỌN phím

25

VK_PRINT

Phím IN

26

VK_EXECUTE

Phím THỰC HIỆN

27

VK_SNAPSHOT

Phím IN MÀN HÌNH

28

VK_INSERT

Phím INS

29

VK_DELETE

Phím DEL

30

VK_NUMPAD0

Bàn phím số 0 phím

31

VK_NUMPAD1

Bàn phím số 1 phím

32

VK_NUMPAD2

Bàn phím số 2 phím

33

VK_NUMPAD3

Bàn phím số 3 phím

34

VK_NUMPAD4

Bàn phím số 4 phím

35

VK_NUMPAD5

Bàn phím số 5 phím

36

VK_NUMPAD6

Bàn phím số 6 phím

37

VK_NUMPAD7

Bàn phím số 7 phím

38

VK_NUMPAD8

Bàn phím số 8 phím

39

VK_NUMPAD9

Bàn phím số 9 phím

40

VK_MULTIPLY

Phím nhân

41

VK_ADD

Thêm khóa

42

VK_SEPARATOR

Phím phân cách

43

VK_SUBTRACT

Trừ khóa

44

VK_DECIMAL

Khóa thập phân

45

VK_DIVIDE

Chìa khóa chia

46

VK_F1

Phím F1

47

VK_F2

Phím F2

48

VK_F3

Phím F3

49

VK_F4

Phím F4

50

VK_F5

Phím F5

52

VK_F6

Phím F6

53

VK_F7

Phím F7

54

VK_F8

Phím F8

55

VK_F9

Phím F9

56

VK_F10

Phím F10

57

VK_F11

Phím F11

58

VK_F12

Phím F12

59

VK_NUMLOCK

Khóa NUM LOCK

60

VK_SCROLL

Phím SCROLL LOCK

61

VK_LSHIFT

Phím SHIFT trái

62

VK_RSHIFT

Phím SHIFT phải

63

VK_LCONTROL

Phím CONTROL bên trái

64

VK_RCONTROL

Phím ĐIỀU KHIỂN bên phải

Nhấn một phím sẽ đưa thông báo WM_KEYDOWN hoặc WM_SYSKEYDOWN vào tin nhắn chuỗi. Điều này có thể được định nghĩa như sau:

afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);

Chúng ta hãy xem xét một ví dụ đơn giản.

Step 1 - Đây là tin nhắn.

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
   ON_WM_CREATE()
   ON_WM_KEYDOWN()
END_MESSAGE_MAP()

Step 2 - Đây là phần triển khai của OnKeyDown ().

void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {
   switch (nChar) {

      case VK_RETURN:
         MessageBox(L"You pressed Enter");
         break;
      case VK_F1:
         MessageBox(L"Help is not available at the moment");
         break;
      case VK_DELETE:
         MessageBox(L"Can't Delete This");
         break;
      default:
         MessageBox(L"Whatever");
   }
}

Step 3 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 4 - Khi bạn nhấn Enter, nó sẽ hiển thị thông báo sau.

Tin nhắn chuột

Chuột là một vật khác được gắn vào máy tính cho phép người dùng tương tác với máy.

  • Nếu nút chuột trái được nhấn, một thông báo ON_WM_LBUTTONDOWN sẽ được gửi. Cú pháp của tin nhắn này là -

    • afx_msg void OnLButtonDown (UINT nFlags, CPoint point)

  • Nếu nút chuột phải được nhấn, một thông báo ON_WM_RBUTTONDOWN sẽ được gửi. Cú pháp của nó là -

    • afx_msg void OnRButtonDown (UINT nFlags, CPoint point)

  • Tương tự Nếu chuột trái đang được thả, thông báo ON_WM_LBUTTONUP sẽ được gửi. Cú pháp của nó là -

    • afx_msg void OnLButtonUp (UINT nFlags, CPoint point)

  • Nếu thả chuột phải, thông báo ON_WM_TBUTTONUP sẽ được gửi. Cú pháp của nó là -

    • afx_msg void OnRButtonUp (UINT nFlags, CPoint point)

Chúng ta hãy xem xét một ví dụ đơn giản.

Step 1 - Thêm hai hàm sau trong định nghĩa lớp CMainFrame như được hiển thị trong đoạn mã sau.

class CMainFrame : public CFrameWnd {
   public:
      CMainFrame();
   protected:
      afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
      afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
      afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
      DECLARE_MESSAGE_MAP()
};

Step 2 - Thêm hai Bản đồ tin nhắn sau.

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
   ON_WM_KEYDOWN()
   ON_WM_LBUTTONDOWN()
   ON_WM_RBUTTONUP()
END_MESSAGE_MAP()

Step 3 - Đây là định nghĩa các hàm.

void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point) { 
   CString MsgCoord;
   MsgCoord.Format(L"Left Button at P(%d, %d)", point.x, point.y);
   MessageBox(MsgCoord);
}
void CMainFrame::OnRButtonUp(UINT nFlags, CPoint point) { 
   MessageBox(L"Right Mouse Button Up");
}

Step 4 - Khi bạn chạy ứng dụng này, bạn sẽ thấy kết quả sau.

Step 5 - Khi bấm OK, bạn sẽ thấy thông báo sau.

Step 6- Nhấp chuột phải vào cửa sổ này. Bây giờ, khi bạn thả nút phải của chuột, nó sẽ hiển thị thông báo sau.

An ActiveX control container là chương trình mẹ cung cấp môi trường để điều khiển ActiveX (trước đây là OLE) chạy.

  • Điều khiển ActiveX là điều khiển sử dụng các công nghệ ActiveX của Microsoft.

  • ActiveX không phải là một ngôn ngữ lập trình, mà là một tập hợp các quy tắc về cách các ứng dụng nên chia sẻ thông tin.

  • Các lập trình viên có thể phát triển các điều khiển ActiveX bằng nhiều ngôn ngữ khác nhau, bao gồm C, C ++, Visual Basic và Java.

  • Bạn có thể tạo một ứng dụng có khả năng chứa các điều khiển ActiveX có hoặc không có MFC, nhưng với MFC thì dễ dàng hơn nhiều.

Hãy để chúng tôi xem xét ví dụ đơn giản về thêm điều khiển ActiveX trong ứng dụng dựa trên hộp thoại MFC của bạn.

Step 1 - Nhấp chuột phải vào hộp thoại trong cửa sổ trình thiết kế và chọn Insert ActiveX Control.

Step 2 - Chọn Microsoft Picture Clip Control và nhấp vào OK.

Step 3 - Thay đổi kích thước điều khiển Hình ảnh và trong cửa sổ Thuộc tính, nhấp vào trường Hình ảnh.

Step 4- Duyệt thư mục có chứa Hình ảnh. Chọn bất kỳ hình ảnh nào.

Step 5 - Khi bạn chạy ứng dụng này, bạn sẽ thấy kết quả sau.

Hãy để chúng tôi xem xét một ví dụ đơn giản khác.

Step 1 - Nhấp chuột phải vào hộp thoại trong cửa sổ trình thiết kế.

Step 2 - Chọn Chèn điều khiển ActiveX.

Step 3 - Chọn Microsoft ProgressBar Control 6.0, bấm OK.

Step 4 - Chọn thanh tiến trình và đặt Hướng của nó trong Cửa sổ Thuộc tính thành 1 – ccOrientationVertical.

Step 5 - Thêm biến điều khiển cho thanh Tiến trình.

Step 6 - Thêm mã sau vào OnInitDialog ()

m_progBarCtrl.SetScrollRange(0,100,TRUE);
m_progBarCtrl.put_Value(53);

Step 7 - Khi bạn chạy lại ứng dụng này, bạn cũng sẽ thấy thanh tiến trình ở Hướng dọc.

Trong chương này, chúng ta sẽ thảo luận về các thành phần khác nhau của hệ thống tệp.

Ổ đĩa

A drivelà một thiết bị vật lý được gắn vào máy tính để nó có thể lưu trữ thông tin. Đĩa logic, ổ đĩa logic hoặc đĩa ảo (viết tắt là VD hoặc vdisk) là một thiết bị ảo cung cấp vùng dung lượng lưu trữ có thể sử dụng trên một hoặc nhiều ổ đĩa vật lý trong hệ thống máy tính. Ổ đĩa có thể là đĩa cứng, CD ROM, DVD ROM, ổ flash (USB), thẻ nhớ, v.v.

Một trong những thao tác chính bạn sẽ muốn thực hiện là lấy danh sách các ổ đĩa trên máy tính.

Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một ứng dụng dựa trên hộp thoại MFC mới.

Step 1 - Kéo một nút từ hộp công cụ, thay đổi Chú thích của nó thành Nhận Thông tin Ổ đĩa.

Step 2 - Bỏ chú thích của điều khiển tĩnh (dòng TODO) và thay đổi ID của nó thành IDC_STATIC_TEXT.

Step 3 - Nhấp chuột phải vào nút và chọn Add Event Handler.

Step 4 - Chọn loại tin nhắn BN_CLICKED và nhấp vào nút Thêm và Chỉnh sửa.

Step 5 - Thêm biến giá trị m_strDrives để điều khiển Văn bản tĩnh.

Để hỗ trợ các ổ đĩa trên máy tính, thư viện Win32 cung cấp hàm GetLogicalDrives () của Microsoft Window, hàm này sẽ truy xuất danh sách tất cả các ổ đĩa trên máy tính hiện tại.

Step 6 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 7 - Khi bạn nhấp vào nút, bạn có thể xem tất cả các ổ đĩa trên máy tính của mình.

Thư mục

Trong máy tính, một directorylà một cấu trúc danh mục hệ thống tệp chứa các tham chiếu đến các tệp máy tính khác và có thể là các thư mục khác. Thư mục là một vị trí thực tế. Nó có thể xử lý các hoạt động không có sẵn trên ổ đĩa.

Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một ứng dụng dựa trên hộp thoại MFC mới

Step 1- Kéo ba nút từ hộp công cụ. Thay đổi Chú thích của họ để Tạo Thư mục, Xóa Thư mục và Di chuyển Thư mục.

Step 2 - Thay đổi ID của các nút này thành IDC_BUTTON_CREATE, IDC_BUTTON_DELETEIDC_BUTTON_MOVE.

Step 3 - Bỏ dòng TODO.

Step 4 - Thêm trình xử lý sự kiện cho mỗi nút.

Step 5 - Để tạo thư mục, bạn có thể gọi phương thức CreateDirectory () của thư viện Win32.

Step 6 - Đây là phần triển khai trình xử lý sự kiện nút Create, trong đó chúng ta sẽ tạo một thư mục và sau đó là hai thư mục con nữa.

void CMFCDirectoriesDemoDlg::OnBnClickedButtonCreate() {
   // TODO: Add your control notification handler code here
   SECURITY_ATTRIBUTES saPermissions;

   saPermissions.nLength = sizeof(SECURITY_ATTRIBUTES);
   saPermissions.lpSecurityDescriptor = NULL;
   saPermissions.bInheritHandle = TRUE;

   if (CreateDirectory(L"D:\\MFCDirectoryDEMO", &saPermissions) == TRUE)
      AfxMessageBox(L"The directory was created.");
   CreateDirectory(L"D:\\MFCDirectoryDEMO\\Dir1", NULL);
   CreateDirectory(L"D:\\MFCDirectoryDEMO\\Dir2", NULL);
}

Step 7 - Để thoát khỏi một danh bạ, bạn có thể gọi RemoveDirectory()chức năng của thư viện Win32. Đây là việc thực hiện xử lý sự kiện nút xóa.

void CMFCDirectoriesDemoDlg::OnBnClickedButtonDelete() {
   // TODO: Add your control notification handler code here
   if (RemoveDirectory(L"D:\\MFCDirectoryDEMO\\Dir1") == TRUE)
      AfxMessageBox(L"The directory has been deleted");
}

Step 8- Nếu bạn muốn di chuyển một thư mục, bạn cũng có thể gọi hàm MoveFile () tương tự. Đây là việc thực hiện trình xử lý sự kiện nút di chuyển, trong đó chúng ta sẽ tạo thư mục mới đầu tiên và sau đó di chuyển Dir2 đến thư mục đó.

void CMFCDirectoriesDemoDlg::OnBnClickedButtonMove() {
   // TODO: Add your control notification handler code here
   CreateDirectory(L"D:\\MFCDirectory", NULL);

   if (MoveFile(L"D:\\MFCDirectoryDEMO\\Dir1", L"D:\\MFCDirectory\\Dir1") == TRUE)
      AfxMessageBox(L"The directory has been moved");
}

Step 9 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 10 - Khi nhấn vào nút Create Directory, nó sẽ tạo ra các thư mục này.

Step 11 - Khi bạn bấm vào nút Delete Directory, nó sẽ xóa Dir1.

Xử lý tệp

Hầu hết các file processing trong một ứng dụng MFC được thực hiện cùng với một lớp có tên CArchive. Lớp CArchive đóng vai trò như một chuyển tiếp giữa ứng dụng và phương tiện được sử dụng để lưu trữ dữ liệu hoặc cung cấp cho nó. Nó cho phép bạn lưu một mạng phức tạp của các đối tượng ở dạng nhị phân vĩnh viễn (thường là ổ lưu trữ) vẫn tồn tại sau khi các đối tượng đó bị xóa.

Đây là danh sách các phương thức trong lớp CArchive -

Sr.No. Tên & Mô tả
1

Abort

Đóng một kho lưu trữ mà không đưa ra một ngoại lệ.

2

Close

Xả dữ liệu không thành văn và ngắt kết nối khỏi CFile.

3

Flush

Xả dữ liệu chưa được viết ra khỏi bộ đệm lưu trữ.

4

GetFile

Nhận con trỏ đối tượng CFile cho kho lưu trữ này.

5

GetObjectSchema

Được gọi từ Serialize chức năng để xác định phiên bản của đối tượng đang được deserialized.

6

IsBufferEmpty

Xác định xem bộ đệm đã được làm trống trong quá trình nhận Windows Sockets.

7

IsLoading

Xác định xem tệp lưu trữ có đang tải hay không.

số 8

IsStoring

Xác định xem kho lưu trữ có được lưu trữ hay không.

9

MapObject

Đặt các đối tượng trong bản đồ không được tuần tự hóa vào tệp, nhưng có sẵn cho các subobject để tham khảo.

10

Read

Đọc các byte thô.

11

ReadClass

Đọc tham chiếu lớp được lưu trữ trước đó với WriteClass.

12

ReadObject

Gọi hàm Serialize của một đối tượng để tải.

13

ReadString

Đọc một dòng văn bản.

14

SerializeClass

Đọc hoặc ghi tham chiếu lớp tới đối tượng CArchive tùy thuộc vào hướng của CArchive.

15

SetLoadParams

Đặt kích thước mà mảng tải tăng lên. Phải được gọi trước khi bất kỳ đối tượng nào được tải hoặc trướcMapObject hoặc là ReadObject được gọi là.

16

SetObjectSchema

Đặt lược đồ đối tượng được lưu trữ trong đối tượng lưu trữ.

17

SetStoreParams

Đặt kích thước bảng băm và kích thước khối của bản đồ được sử dụng để xác định các đối tượng duy nhất trong quá trình tuần tự hóa.

18

Write

Viết các byte thô.

19

WriteClass

Viết một tham chiếu đến CRuntimeClass vào CArchive.

20

WriteObject

Gọi hàm Serialize của một đối tượng để lưu trữ.

21

WriteString

Viết một dòng văn bản.

Đây là danh sách các toán tử được sử dụng để lưu trữ và truy xuất dữ liệu

Sr.No. Tên & Mô tả
1

operator <<

Lưu trữ các đối tượng và kiểu nguyên thủy vào kho lưu trữ.

2

operator >>

Tải các đối tượng và kiểu nguyên thủy từ kho lưu trữ.

Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một ứng dụng dựa trên hộp thoại MFC mới.

Step 1 - Kéo một điều khiển chỉnh sửa và hai nút như thể hiện trong ảnh chụp nhanh sau đây.

Step 2 - Thêm biến điều khiển m_editCtrl và biến giá trị m_strEdit để kiểm soát chỉnh sửa.

Step 3 - Thêm trình xử lý sự kiện nhấp chuột cho các nút Mở và Lưu.

Step 4 - Đây là việc thực hiện các trình xử lý sự kiện.

void CMFCFileProcessingDlg::OnBnClickedButtonOpen() {
   // TODO: Add your control notification handler code here
   UpdateData(TRUE);
   
   CFile file;
   
   file.Open(L"ArchiveText.rpr", CFile::modeRead);
   if(file) {
      CArchive ar(&file, CArchive::load);
   
      ar >> m_strEdit;
   
      ar.Close();
      file.Close();
   }
   UpdateData(FALSE);
}

void CMFCFileProcessingDlg::OnBnClickedButtonSave() {
   // TODO: Add your control notification handler code here
   UpdateData(TRUE);

   if (m_strEdit.GetLength() == 0) {
      AfxMessageBox(L"You must enter the name of the text.");
      return;
   }
   CFile file;
   
   file.Open(L"ArchiveText.rpr", CFile::modeCreate | CFile::modeWrite);
   CArchive ar(&file, CArchive::store);
   ar << m_strEdit;
   
   ar.Close();
   file.Close();
}

Step 5 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 6- Viết một cái gì đó và nhấp vào Lưu. Nó sẽ lưu dữ liệu ở định dạng nhị phân.

Step 7- Xóa bài kiểm tra khỏi kiểm soát chỉnh sửa. Khi bạn nhấp vào Mở, hãy quan sát rằng cùng một văn bản được tải lại.

Thư viện MFC cung cấp phiên bản xử lý tệp của riêng nó. Điều này được thực hiện thông qua một lớp có tên CStdioFile. Lớp CStdioFile có nguồn gốc từ CFile. Nó có thể xử lý việc đọc và ghi các tệp văn bản Unicode cũng như các tệp văn bản nhiều byte thông thường.

Đây là danh sách các hàm tạo, có thể khởi tạo đối tượng CStdioFile -

CStdioFile();
CStdioFile(CAtlTransactionManager* pTM);
CStdioFile(FILE* pOpenStream);
CStdioFile(LPCTSTR lpszFileName, UINT nOpenFlags);
CStdioFile(LPCTSTR lpszFileName, UINT nOpenFlags, CAtlTransactionManager* pTM);

Đây là danh sách các phương thức trong CStdioFile -

Sr.No. Tên & Mô tả
1

Open

Quá tải. Open được thiết kế để sử dụng với phương thức khởi tạo CStdioFile mặc định (Ghi đè CFile :: Open).

2

ReadString

Đọc một dòng văn bản.

3

Seek

Định vị con trỏ tệp hiện tại.

4

WriteString

Viết một dòng văn bản.

Chúng ta hãy xem xét lại một ví dụ đơn giản bằng cách tạo một ứng dụng dựa trên hộp thoại MFC mới.

Step 1 - Kéo một điều khiển chỉnh sửa và hai nút như thể hiện trong ảnh chụp nhanh sau đây.

Step 2 - Thêm biến giá trị m_strEditCtrl để kiểm soát chỉnh sửa.

Step 3 - Thêm trình xử lý sự kiện nhấp chuột cho các nút Mở và Lưu.

Step 4 - Đây là việc thực hiện các trình xử lý sự kiện.

void CMFCStandardIODlg::OnBnClickedButtonOpen() {
   
   // TODO: Add your control notification handler code here
   UpdateData(TRUE);

   CStdioFile file;
   file.Open(L"D:\\MFCDirectoryDEMO\\test.txt", CFile::modeRead | CFile::typeText);
   
   file.ReadString(m_strEditCtrl);
   file.Close();
   UpdateData(FALSE);
}

void CMFCStandardIODlg::OnBnClickedButtonSave() {
   
   // TODO: Add your control notification handler code here
   UpdateData(TRUE);
   CStdioFile file;
   if (m_strEditCtrl.GetLength() == 0) {

      AfxMessageBox(L"You must specify the text.");
      return;
   }
   file.Open(L"D:\\MFCDirectoryDEMO\\test.txt", CFile::modeCreate |
      CFile::modeWrite | CFile::typeText);
   file.WriteString(m_strEditCtrl);
   file.Close();
}

Step 5 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 6- Viết một cái gì đó và nhấp vào Lưu. Nó sẽ lưu dữ liệu trong tệp * .txt.

Step 7 - Nếu bạn nhìn vào vị trí của tệp, bạn sẽ thấy rằng nó chứa tệp test.txt.

Step 8- Bây giờ, đóng ứng dụng. Chạy cùng một ứng dụng. Khi bạn nhấp vào Mở, cùng một văn bản sẽ tải lại.

Step 9 - Nó bắt đầu bằng cách mở tệp, đọc tệp, tiếp theo là cập nhật Điều khiển chỉnh sửa.

Các Document/View architecturelà nền tảng được sử dụng để tạo các ứng dụng dựa trên thư viện Microsoft Foundation Classes. Nó cho phép bạn phân biệt các phần khác nhau tạo nên một chương trình máy tính bao gồm những gì người dùng xem như một phần của ứng dụng của bạn và tài liệu mà người dùng sẽ làm việc. Điều này được thực hiện thông qua sự kết hợp của các lớp riêng biệt hoạt động như một nhóm.

Các phần tạo cấu trúc Tài liệu / Dạng xem là một khung, một hoặc nhiều tài liệu và dạng xem. Tổng hợp lại, các thực thể này tạo nên một ứng dụng có thể sử dụng được.

Lượt xem

A viewlà nền tảng mà người dùng đang sử dụng để thực hiện công việc của mình. Để cho phép người dùng làm bất cứ điều gì trên một ứng dụng, bạn phải cung cấp một dạng xem, đây là một đối tượng dựa trên lớp CView. Bạn có thể trực tiếp sử dụng một trong các lớp dẫn xuất từ ​​CView hoặc bạn có thể lấy lớp tùy chỉnh của riêng mình từ CView hoặc một trong các lớp con của nó.

Tài liệu

A documenttương tự như một cái xô. Đối với ứng dụng máy tính, tài liệu lưu giữ dữ liệu của người dùng. Để tạo phần tài liệu của kiến ​​trúc này, bạn phải lấy một đối tượng từ lớp CDocument.

Khung

Như tên cho thấy, một framelà sự kết hợp của các khối xây dựng, cấu trúc và đường viền của một mục. Khung cung cấp sự hiện diện "vật lý" cho một cửa sổ. Nó cũng xác định vị trí của một đối tượng liên quan đến màn hình Windows.

Giao diện tài liệu đơn (SDI)

Cách diễn đạt Single Document Interfacehoặc SDI đề cập đến một tài liệu chỉ có thể hiển thị một chế độ xem cho người dùng. Điều này có nghĩa là ứng dụng không thể hiển thị nhiều hơn một tài liệu cùng một lúc. Nếu bạn muốn xem một loại tài liệu khác của ứng dụng hiện tại, bạn phải tạo một phiên bản khác của ứng dụng. Notepad và WordPad là những ví dụ về ứng dụng SDI.

Chúng ta hãy xem xét một ví dụ đơn giản về giao diện tài liệu đơn lẻ hoặc SDI bằng cách tạo một ứng dụng dựa trên hộp thoại MFC mới.

Step 1 - Hãy để chúng tôi tạo một Ứng dụng MFC mới MFCSDIDemo với các cài đặt được đề cập bên dưới.

Step 2 - Chọn Tài liệu đơn từ Kiểu ứng dụng và tiêu chuẩn MFC từ Kiểu dự án.

Step 3 - Bấm Hoàn tất để Tiếp tục.

Step 4 - Sau khi dự án được tạo, hãy chạy ứng dụng và bạn sẽ thấy kết quả sau.

Nhiều giao diện tài liệu (MDI)

Một ứng dụng được gọi là Multiple Document Interfacehoặc MDI, nếu người dùng có thể mở nhiều tài liệu trong ứng dụng mà không cần đóng tài liệu đó. Để cung cấp chức năng này, ứng dụng cung cấp một khung mẹ đóng vai trò là khung chính của chương trình máy tính. Bên trong khung này, ứng dụng cho phép tạo các khung nhìn với các khung riêng lẻ, làm cho mỗi khung nhìn khác biệt với khung khác.

Chúng ta hãy xem xét một ví dụ đơn giản về giao diện nhiều tài liệu hoặc MDI bằng cách tạo một ứng dụng dựa trên hộp thoại MFC mới.

Step 1 - Hãy để chúng tôi tạo một Ứng dụng MFC mới MFCMDIDemo với các cài đặt được đề cập bên dưới.

Step 2 - Chọn Nhiều tài liệu từ Kiểu ứng dụng và tiêu chuẩn MFC từ Kiểu dự án.

Step 3 - Bấm Hoàn tất để Tiếp tục.

Step 4 - Sau khi dự án được tạo, hãy chạy ứng dụng và bạn sẽ thấy kết quả sau.

Step 5 - Khi bạn nhấp vào tùy chọn menu File → New, nó sẽ tạo ra một cửa sổ con khác như trong ảnh chụp sau.

Step 6- Trong các ứng dụng Giao diện Nhiều Tài liệu (MDI), có một khung chính cho mỗi ứng dụng. Trong trường hợp này, một CMDIFrameWnd và một khung con dẫn xuất CMDIChildWnd cho mỗi tài liệu.

Stringslà các đối tượng biểu diễn chuỗi các ký tự. Chuỗi ký tự kiểu C bắt nguồn từ ngôn ngữ C và tiếp tục được hỗ trợ trong C ++.

  • Chuỗi này thực sự là một mảng một chiều các ký tự được kết thúc bằng một ký tự rỗng '\ 0'.

  • Chuỗi được kết thúc bằng null chứa các ký tự bao gồm chuỗi theo sau là null.

Đây là ví dụ đơn giản về mảng ký tự.

char word[12] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '\0' };

Sau đây là một cách khác để biểu diễn nó.

char word[] = "Hello, World";

Thư viện Microsoft Foundation Class (MFC) cung cấp một lớp để thao tác với chuỗi được gọi là CString. Sau đây là một số tính năng quan trọng của CString.

  • CString không có lớp cơ sở.

  • Đối tượng CString bao gồm một chuỗi ký tự có độ dài thay đổi.

  • CString cung cấp các hàm và toán tử sử dụng cú pháp tương tự như cú pháp của Basic.

  • Các toán tử nối và so sánh, cùng với việc quản lý bộ nhớ được đơn giản hóa, làm cho các đối tượng CString dễ sử dụng hơn các mảng ký tự thông thường.

Đây là hàm tạo của CString.

Sr.No. Phương pháp & Mô tả
1

CString

Xây dựng các đối tượng CString theo nhiều cách khác nhau

Đây là danh sách các Phương thức Mảng -

Sr.No. Phương pháp & Mô tả
1

GetLength

Trả về số ký tự trong đối tượng CString.

2

IsEmpty

Kiểm tra xem một đối tượng CString không chứa ký tự nào.

3

Empty

Buộc một chuỗi có độ dài bằng 0.

4

GetAt

Trả về ký tự tại một vị trí được chỉ định.

5

SetAt

Đặt một ký tự ở một vị trí được chỉ định.

Đây là danh sách các phương pháp so sánh -

Sr.No. Phương pháp & Mô tả
1

Compare

So sánh hai chuỗi (phân biệt chữ hoa chữ thường).

2

CompareNoCase

So sánh hai chuỗi (không phân biệt chữ hoa chữ thường).

Đây là danh sách các phương pháp trích xuất -

Sr.No. Phương pháp & Mô tả
1

Mid

Trích xuất phần giữa của một chuỗi (như hàm MID $ cơ bản).

2

Left

Trích xuất phần bên trái của một chuỗi (như hàm Basic LEFT $).

3

Right

Trích xuất phần bên phải của một chuỗi (như hàm Basic RIGHT $).

4

SpanIncluding

Trích xuất các ký tự từ chuỗi nằm trong bộ ký tự đã cho.

5

SpanExcluding

Trích xuất các ký tự từ chuỗi không có trong bộ ký tự đã cho.

Đây là danh sách các phương pháp chuyển đổi.

Sr.No. Phương pháp & Mô tả
1

MakeUpper

Chuyển đổi tất cả các ký tự trong chuỗi này thành các ký tự viết hoa.

2

MakeLower

Chuyển đổi tất cả các ký tự trong chuỗi này thành các ký tự viết thường.

3

MakeReverse

Đảo ngược các ký tự trong chuỗi này.

4

Format

Định dạng chuỗi như sprintf.

5

TrimLeft

Cắt các ký tự khoảng trắng hàng đầu khỏi chuỗi.

6

TrimRight

Cắt các ký tự khoảng trắng theo sau khỏi chuỗi.

Đây là danh sách các Phương pháp Tìm kiếm.

Sr.No. Phương pháp & Mô tả
1

Find

Tìm một ký tự hoặc chuỗi con bên trong một chuỗi lớn hơn.

2

ReverseFind

Tìm một ký tự bên trong một chuỗi lớn hơn; bắt đầu từ cuối.

3

FindOneOf

Tìm ký tự phù hợp đầu tiên từ một tập hợp.

Đây là danh sách các Phương pháp Truy cập Bộ đệm.

Sr.No. Phương pháp & Mô tả
1

GetBuffer

Trả về một con trỏ đến các ký tự trong CString.

2

GetBufferSetLength

Trả về một con trỏ đến các ký tự trong CString, cắt bớt theo độ dài được chỉ định.

3

ReleaseBuffer

Giải phóng quyền kiểm soát bộ đệm do GetBuffer trả về

4

FreeExtra

Loại bỏ mọi chi phí của đối tượng chuỗi này bằng cách giải phóng bất kỳ bộ nhớ bổ sung nào đã được cấp phát trước đó cho chuỗi.

5

LockBuffer

Tắt tính năng đếm tham chiếu và bảo vệ chuỗi trong bộ đệm.

6

UnlockBuffer

Cho phép đếm tham chiếu và giải phóng chuỗi trong bộ đệm.

Đây là danh sách các Phương pháp dành riêng cho Windows.

Sr.No. Phương pháp & Mô tả
1

AllocSysString

Phân bổ BSTR từ dữ liệu CString.

2

SetSysString

Đặt đối tượng BSTR hiện có với dữ liệu từ đối tượng CString.

3

LoadString

Tải đối tượng CString hiện có từ tài nguyên Windows CE.

Sau đây là các hoạt động khác nhau trên các đối tượng CString:

Tạo chuỗi

Bạn có thể tạo một chuỗi bằng cách sử dụng một chuỗi ký tự hoặc tạo một thể hiện của lớp CString.

BOOL CMFCStringDemoDlg::OnInitDialog() {

   CDialogEx::OnInitDialog();

   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);         // Set big icon
   SetIcon(m_hIcon, FALSE);       // Set small icon

   CString string1 = _T("This is a string1");
   CString string2("This is a string2");

   m_strText.Append(string1 + L"\n");
   m_strText.Append(string2);

   UpdateData(FALSE);

   return TRUE; // return TRUE unless you set the focus to a control
}

Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả sau.

Chuỗi trống

Bạn có thể tạo một chuỗi rỗng bằng cách sử dụng một chuỗi rỗng theo nghĩa đen hoặc bằng cách sử dụng phương thức CString :: Empty (). Bạn cũng có thể kiểm tra xem một chuỗi có trống hay không bằng cách sử dụng thuộc tính Boolean isEmpty.

BOOL CMFCStringDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);            // Set big icon
   SetIcon(m_hIcon, FALSE);           // Set small icon

   CString string1 = _T("");
   CString string2;
   string2.Empty();

   if(string1.IsEmpty())
      m_strText.Append(L"String1 is empty\n");
   else
      m_strText.Append(string1 + L"\n");
   
   if(string2.IsEmpty())
      m_strText.Append(L"String2 is empty");
   else
      m_strText.Append(string2);
   UpdateData(FALSE);
   return TRUE; // return TRUE unless you set the focus to a control
}

Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả sau.

Kết nối chuỗi

Để nối hai hoặc nhiều chuỗi, bạn có thể sử dụng toán tử + để nối hai chuỗi hoặc phương thức CString :: Append ().

BOOL CMFCStringDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);              // Set big icon
   SetIcon(m_hIcon, FALSE);              // Set small icon

   //To concatenate two CString objects
   CString s1 = _T("This ");           // Cascading concatenation
   s1 += _T("is a ");
   CString s2 = _T("test");
   CString message = s1;
   message.Append(_T("big ") + s2);
   // Message contains "This is a big test".

   m_strText = L"message: " + message;

   UpdateData(FALSE);

   return TRUE; // return TRUE unless you set the focus to a control
}

Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả sau.

Chiều dài chuỗi

Để tìm độ dài của chuỗi, bạn có thể sử dụng phương thức CString :: GetLength (), phương thức này trả về số ký tự trong một đối tượng CString.

BOOL CMFCStringDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();
   
   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);              // Set big icon
   SetIcon(m_hIcon, FALSE);              // Set small icon

   CString string1 = _T("This is string 1");
   int length = string1.GetLength();
   CString strLen;

   strLen.Format(L"\nString1 contains %d characters", length);
   m_strText = string1 + strLen;

   UpdateData(FALSE);

   return TRUE; // return TRUE unless you set the focus to a control
}

Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả sau.

So sánh chuỗi

Để so sánh hai biến chuỗi, bạn có thể sử dụng toán tử ==

BOOL CMFCStringDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();
   
   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);            // Set big icon
   SetIcon(m_hIcon, FALSE);          // Set small icon

   CString string1 = _T("Hello");
   CString string2 = _T("World");

   CString string3 = _T("MFC Tutorial");
   CString string4 = _T("MFC Tutorial");

   if (string1 == string2)
      m_strText = "string1 and string1 are same\n";
   else
      m_strText = "string1 and string1 are not same\n";

   if (string3 == string4)
      m_strText += "string3 and string4 are same";
   else
      m_strText += "string3 and string4 are not same";

   UpdateData(FALSE);

   return TRUE; // return TRUE unless you set the focus to a control
}

Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả sau.

CArraylà một tập hợp được sử dụng tốt nhất cho dữ liệu được truy cập theo cách ngẫu nhiên hoặc không theo trình tự. Lớp CArray hỗ trợ các mảng giống như mảng C, nhưng có thể tự động thu nhỏ và phát triển khi cần thiết.

  • Chỉ mục mảng luôn bắt đầu từ vị trí 0.

  • Bạn có thể quyết định sửa giới hạn trên hoặc cho phép mở rộng mảng khi bạn thêm các phần tử vượt qua giới hạn hiện tại.

  • Bộ nhớ được cấp phát liên tục cho giới hạn trên, ngay cả khi một số phần tử là rỗng.

Sr.No. Tên & Mô tả
1

Add

Thêm một phần tử vào cuối mảng; phát triển mảng nếu cần thiết.

2

Append

Thêm mảng khác vào mảng; phát triển mảng nếu cần thiết

3

Copy

Sao chép mảng khác vào mảng; phát triển mảng nếu cần thiết.

4

ElementAt

Trả về một tham chiếu tạm thời đến con trỏ phần tử trong mảng.

5

FreeExtra

Giải phóng tất cả bộ nhớ không sử dụng trên giới hạn trên hiện tại.

6

GetAt

Giải phóng tất cả bộ nhớ không sử dụng trên giới hạn trên hiện tại.

7

GetCount

Nhận số phần tử trong mảng này.

số 8

GetData

Cho phép truy cập vào các phần tử trong mảng. Có thểNULL.

9

GetSize

Nhận số phần tử trong mảng này.

10

GetUpperBound

Trả về chỉ mục hợp lệ lớn nhất.

11

InsertAt

Chèn một phần tử (hoặc tất cả các phần tử trong một mảng khác) tại một chỉ mục được chỉ định.

12

IsEmpty

Xác định xem mảng có trống không.

13

RemoveAll

Xóa tất cả các phần tử khỏi mảng này.

14

RemoveAt

Loại bỏ một phần tử tại một chỉ mục cụ thể.

15

SetAt

Đặt giá trị cho một chỉ mục nhất định; mảng không được phép phát triển.

16

SetAtGrow

Đặt giá trị cho một chỉ mục nhất định; phát triển mảng nếu cần thiết.

17

SetSize

Đặt số phần tử được chứa trong mảng này.

Sau đây là các hoạt động khác nhau trên các đối tượng CArray:

Tạo đối tượng CArray

Để tạo một bộ sưu tập các giá trị hoặc đối tượng CArray, trước tiên bạn phải quyết định loại giá trị của bộ sưu tập. Bạn có thể sử dụng một trong các kiểu dữ liệu nguyên thủy hiện có như int, CString, double, v.v. như hình dưới đây;

CArray<CString, CString>strArray;

Thêm các mục

Để thêm một mục, bạn có thể sử dụng hàm CArray :: Add (). Nó thêm một mục vào cuối mảng. Trong đối tượng OnInitDialog (), CArray được tạo và ba tên được thêm vào như thể hiện trong đoạn mã sau.

CArray<CString, CString>strArray;

//Add names to CArray
strArray.Add(L"Ali");
strArray.Add(L"Ahmed");
strArray.Add(L"Mark");

Lấy các mục

Để lấy bất kỳ mục nào, bạn có thể sử dụng hàm CArray :: GetAt (). Hàm này nhận một tham số số nguyên làm chỉ số của mảng.

Step 1 - Chúng ta hãy xem một ví dụ đơn giản, sẽ lấy ra tất cả các tên.

//Retrive names from CArray
   for (int i = 0; i < strArray.GetSize(); i++) {
      m_strText.Append(strArray.GetAt(i) + L"\n");
   }

Step 2 - Đây là quá trình triển khai đầy đủ của CMFCCArrayDlg :: OnInitDialog ()

BOOL CMFCCArrayDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);               // Set big icon
   SetIcon(m_hIcon, FALSE);             // Set small icon

   // TODO: Add extra initialization here
   CArray<CString, CString>strArray;
   
   //Add names to CArray
   strArray.Add(L"Ali");
   strArray.Add(L"Ahmed");
   strArray.Add(L"Mark");
   
   //Retrive names from CArray
   for (int i = 0; i < strArray.GetSize(); i++) {
      m_strText.Append(strArray.GetAt(i) + L"\n");
   }
   
   UpdateData(FALSE);
   return TRUE; // return TRUE unless you set the focus to a control
}

Step 3 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Thêm các mục ở giữa

Để thêm mục vào giữa mảng, bạn có thể sử dụng hàm CArray ::. InsertAt (). Nó cần hai tham số - Thứ nhất, chỉ số và Thứ hai, giá trị.

Hãy để chúng tôi chèn một mục mới tại chỉ mục 1 như được hiển thị trong đoạn mã sau.

BOOL CMFCCArrayDlg::OnInitDialog() {
   
   CDialogEx::OnInitDialog();
   
   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);             // Set big icon
   SetIcon(m_hIcon, FALSE);            // Set small icon

   // TODO: Add extra initialization here
   CArray<CString, CString>strArray;
   //Add names to CArray
   strArray.Add(L"Ali");
   strArray.Add(L"Ahmed");
   strArray.Add(L"Mark");

   strArray.InsertAt(1, L"Allan");

   //Retrive names from CArray
   for (int i = 0; i < strArray.GetSize(); i++) {
      m_strText.Append(strArray.GetAt(i) + L"\n");
   }

   UpdateData(FALSE);
   return TRUE; // return TRUE unless you set the focus to a control
}

Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả sau. Bây giờ bạn có thể thấy tên Allan được đặt làm chỉ mục thứ hai.

Cập nhật giá trị mặt hàng

Để cập nhật mục ở giữa mảng, bạn có thể sử dụng hàm CArray ::. SetAt (). Nó cần hai tham số - Thứ nhất, chỉ số và Thứ hai, giá trị.

Hãy để chúng tôi cập nhật phần tử thứ ba trong mảng như được hiển thị trong đoạn mã sau.

BOOL CMFCCArrayDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);                 // Set big icon
   SetIcon(m_hIcon, FALSE);               // Set small icon

   // TODO: Add extra initialization here
   CArray<CString, CString>strArray;

   //Add names to CArray
   strArray.Add(L"Ali");
   strArray.Add(L"Ahmed");
   strArray.Add(L"Mark");
  
   strArray.InsertAt(1, L"Allan");
   
   strArray.SetAt(2, L"Salman");
   
   //Retrive names from CArray
   for (int i = 0; i < strArray.GetSize(); i++) {
      m_strText.Append(strArray.GetAt(i) + L"\n");
   }

   UpdateData(FALSE);
   return TRUE; // return TRUE unless you set the focus to a control
}

Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả sau. Bây giờ bạn có thể thấy rằng giá trị của phần tử thứ ba đã được cập nhật.

Sao chép mảng

Để sao chép toàn bộ mảng vào một đối tượng CArray khác, bạn có thể sử dụng hàm CArray :: Copy ().

Step1 - Hãy tạo một mảng khác và sao chép tất cả các phần tử từ mảng đầu tiên như được hiển thị trong đoạn mã sau.

BOOL CMFCCArrayDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   // Add "About..." menu item to system menu.

   // IDM_ABOUTBOX must be in the system command range.
   ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
   ASSERT(IDM_ABOUTBOX < 0xF000);
   CMenu* pSysMenu = GetSystemMenu(FALSE);
   if (pSysMenu != NULL) {
      BOOL bNameValid;
      CString strAboutMenu;
      bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
      ASSERT(bNameValid);
      if (!strAboutMenu.IsEmpty()) {
         pSysMenu→AppendMenu(MF_SEPARATOR);
         pSysMenu→AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
      }
   }
   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);               // Set big icon
   SetIcon(m_hIcon, FALSE);              // Set small icon

   // TODO: Add extra initialization here
   CArray<CString, CString>strArray;
   //Add names to CArray
   strArray.Add(L"Ali");
   strArray.Add(L"Ahmed");
   strArray.Add(L"Mark");

   strArray.InsertAt(1, L"Allan");

   strArray.SetAt(2, L"Salman");

   CArray<CString, CString>strArray2;
   strArray2.Copy(strArray);
   //Retrive names from CArray
   for (int i = 0; i < strArray2.GetSize(); i++) {
      m_strText.Append(strArray2.GetAt(i) + L"\n");
   }

   UpdateData(FALSE);
   return TRUE; // return TRUE unless you set the focus to a control
}

Bây giờ bạn có thể thấy rằng chúng tôi đã truy xuất phần tử từ mảng thứ 2 và kết quả giống nhau vì chúng tôi đã sử dụng hàm sao chép.

Xóa các mục

Để loại bỏ bất kỳ mục cụ thể nào, bạn có thể sử dụng hàm CArray :: RemoveAt (). Để xóa tất cả phần tử khỏi danh sách, có thể sử dụng hàm CArray :: RemoveAll ().

Hãy để chúng tôi xóa phần tử thứ hai khỏi một mảng.

BOOL CMFCCArrayDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   SetIcon(m_hIcon, TRUE);             // Set big icon
   SetIcon(m_hIcon, FALSE);            // Set small icon

   // TODO: Add extra initialization here
   CArray<CString, CString>strArray;

   //Add names to CArray
   strArray.Add(L"Ali");
   strArray.Add(L"Ahmed");
   strArray.Add(L"Mark");

   strArray.InsertAt(1, L"Allan");

   strArray.SetAt(2, L"Salman");

   CArray<CString, CString>strArray2;
   strArray2.Copy(strArray);

   strArray2.RemoveAt(1);

   //Retrive names from CArray
   for (int i = 0; i < strArray2.GetSize(); i++) {
      m_strText.Append(strArray2.GetAt(i) + L"\n");
   }

   UpdateData(FALSE);
   return TRUE; // return TRUE unless you set the focus to a control
}

Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả sau. Bây giờ bạn có thể thấy rằng tên Allan không còn là một phần của mảng.

A linked listlà một cấu trúc dữ liệu tuyến tính mà mỗi phần tử là một đối tượng riêng biệt. Mỗi phần tử (chúng tôi sẽ gọi nó là một nút) của danh sách bao gồm hai mục - dữ liệu và một tham chiếu đến nút tiếp theo. Nút cuối cùng có tham chiếu đến null.

Danh sách liên kết là một cấu trúc dữ liệu bao gồm một nhóm các nút cùng đại diện cho một chuỗi. Đó là cách lưu trữ dữ liệu với các cấu trúc để người lập trình có thể tự động tạo một nơi mới để lưu trữ dữ liệu bất cứ khi nào cần thiết. Một số tính năng nổi bật của nó là -

  • Danh sách liên kết là một chuỗi các liên kết chứa các mục.

  • Mỗi liên kết chứa một kết nối đến một liên kết khác.

  • Mỗi mục trong danh sách được gọi là một nút.

  • Nếu danh sách chứa ít nhất một nút, thì một nút mới được định vị là phần tử cuối cùng trong danh sách.

  • Nếu danh sách chỉ có một nút, nút đó đại diện cho mục đầu tiên và mục cuối cùng.

Có hai loại danh sách liên kết -

Danh sách liên kết Singly

Singly Linked Lists là một loại cấu trúc dữ liệu. Trong một danh sách được liên kết đơn lẻ, mỗi nút trong danh sách lưu trữ nội dung của nút và một con trỏ hoặc tham chiếu đến nút tiếp theo trong danh sách.

Danh sách được liên kết gấp đôi

Danh sách được liên kết kép là một cấu trúc dữ liệu được liên kết bao gồm một tập hợp các bản ghi được liên kết tuần tự được gọi là các nút. Mỗi nút chứa hai trường là các tham chiếu đến nút trước và đến nút tiếp theo trong chuỗi các nút.

CList Class

MFC cung cấp một lớp CListlà một triển khai danh sách liên kết mẫu và hoạt động hoàn hảo. Danh sách CList hoạt động giống như danh sách được liên kết kép. Một biến kiểu POSITION là một khóa cho danh sách. Bạn có thể sử dụng biến POSITION như một trình vòng lặp để duyệt qua danh sách một cách tuần tự và làm dấu trang để giữ một vị trí.

Sr.No. Tên & Mô tả
1

AddHead

Thêm một phần tử (hoặc tất cả các phần tử trong một danh sách khác) vào đầu danh sách (tạo một phần tử mới).

2

AddTail

Thêm một phần tử (hoặc tất cả các phần tử trong danh sách khác) vào đuôi của danh sách (tạo một đuôi mới).

3

Find

Nhận vị trí của một phần tử được chỉ định bởi giá trị con trỏ.

4

FindIndex

Lấy vị trí của một phần tử được chỉ định bởi chỉ mục dựa trên số không.

5

GetAt

Đưa phần tử ở một vị trí nhất định.

6

GetCount

Trả về số phần tử trong danh sách này.

7

GetHead

Trả về phần tử đầu của danh sách (không được để trống).

số 8

GetHeadPosition

Trả về vị trí của phần tử đầu của danh sách.

9

GetNext

Nhận phần tử tiếp theo để lặp lại.

10

GetPrev

Lấy phần tử trước đó để lặp lại.

11

GetSize

Trả về số phần tử trong danh sách này.

12

GetTail

Trả về phần tử đuôi của danh sách (không được để trống).

13

GetTailPosition

Trả về vị trí của phần tử đuôi của danh sách.

14

InsertAfter

Chèn một phần tử mới sau một vị trí nhất định.

15

InsertBefore

Chèn một phần tử mới trước một vị trí nhất định.

16

IsEmpty

Kiểm tra điều kiện danh sách trống (không có phần tử).

17

RemoveAll

Xóa tất cả các phần tử khỏi danh sách này.

18

RemoveAt

Xóa một phần tử khỏi danh sách này, được chỉ định theo vị trí.

19

RemoveHead

Xóa phần tử khỏi đầu danh sách.

20

RemoveTail

Xóa phần tử khỏi phần cuối của danh sách.

21

SetAt

Đặt phần tử ở một vị trí nhất định.

Sau đây là các hoạt động khác nhau trên các đối tượng CList:

Tạo đối tượng CList

Để tạo một tập hợp các giá trị hoặc đối tượng CList, trước tiên bạn phải quyết định loại giá trị của tập hợp. Bạn có thể sử dụng một trong các kiểu dữ liệu nguyên thủy hiện có như int, CString, double, v.v. như được hiển thị bên dưới trong đoạn mã sau.

CList<double, double>m_list;

Thêm các mục

Để thêm một mục, bạn có thể sử dụng hàm CList :: AddTail (). Nó thêm một mục vào cuối danh sách. Để thêm một phần tử vào đầu danh sách, bạn có thể sử dụng hàm CList :: AddHead (). Trong CList OnInitDialog (), đối tượng được tạo và bốn giá trị được thêm vào như thể hiện trong đoạn mã sau.

CList<double, double>m_list;

//Add items to the list
m_list.AddTail(100.75);
m_list.AddTail(85.26);
m_list.AddTail(95.78);
m_list.AddTail(90.1);

Lấy các mục

Một biến kiểu POSITION là một khóa cho danh sách. Bạn có thể sử dụng biến POSITION làm trình lặp để duyệt danh sách theo tuần tự.

Step 1 - Để lấy phần tử từ danh sách, chúng ta có thể sử dụng đoạn mã sau để lấy tất cả các giá trị.

//iterate the list
POSITION pos = m_list.GetHeadPosition();
while (pos) { 
   double nData = m_list.GetNext(pos);
   CString strVal;
   strVal.Format(L"%.2f\n", nData);
   m_strText.Append(strVal);
}

Step 2 - Đây là hàm CMFCCListDemoDlg :: OnInitDialog () đầy đủ.

BOOL CMFCCListDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);             // Set big icon
   SetIcon(m_hIcon, FALSE);             // Set small icon

   // TODO: Add extra initialization here
   CList<double, double>m_list;

   //Add items to the list
   m_list.AddTail(100.75);
   m_list.AddTail(85.26);
   m_list.AddTail(95.78);
   m_list.AddTail(90.1);

   //iterate the list
   POSITION pos = m_list.GetHeadPosition();
   while (pos) {
      double nData = m_list.GetNext(pos);
      CString strVal;
      strVal.Format(L"%.f\n", nData);
      m_strText.Append(strVal);
   }

   UpdateData(FALSE);
 
   return TRUE; // return TRUE unless you set the focus to a control
}

Step 3 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Thêm các mục ở giữa

Để thêm mục vào giữa danh sách, bạn có thể sử dụng các hàm CList ::. InsertAfter () và CList ::. InsertBefore (). Cần có hai tham số - Thứ nhất, vị trí (nơi có thể thêm vào) và Thứ hai, giá trị.

Step 1 - Hãy để chúng tôi chèn một mục mới như được hiển thị trong mã followng.

BOOL CMFCCListDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();
   
   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);             // Set big icon
   SetIcon(m_hIcon, FALSE);          // Set small icon

   // TODO: Add extra initialization here
   CList<double, double>m_list;

   //Add items to the list
   m_list.AddTail(100.75);
   m_list.AddTail(85.26);
   m_list.AddTail(95.78);
   m_list.AddTail(90.1);

   POSITION position = m_list.Find(85.26);
   m_list.InsertBefore(position, 200.0);
   m_list.InsertAfter(position, 300.0);

   //iterate the list
   POSITION pos = m_list.GetHeadPosition();
   while (pos) {
      double nData = m_list.GetNext(pos);
      CString strVal;
      strVal.Format(L"%.2f\n", nData);
      m_strText.Append(strVal);
   }

   UpdateData(FALSE);

   return TRUE; // return TRUE unless you set the focus to a control
}

Step 2 - Bây giờ bạn có thể thấy rằng đầu tiên chúng tôi truy xuất vị trí của giá trị 85,26 và sau đó chèn một phần tử vào trước và một phần tử sau giá trị đó.

Step 3 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Cập nhật giá trị mặt hàng

Để cập nhật mục ở giữa mảng, bạn có thể sử dụng hàm CArray ::. SetAt (). Cần có hai tham số - Thứ nhất, vị trí và Thứ hai, giá trị.

Hãy để chúng tôi cập nhật 300.00 đến 400 trong danh sách như được hiển thị trong mã sau.

BOOL CMFCCListDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);              // Set big icon
   SetIcon(m_hIcon, FALSE);            // Set small icon

   // TODO: Add extra initialization here
   CList<double, double>m_list;

   //Add items to the list
   m_list.AddTail(100.75);
   m_list.AddTail(85.26);
   m_list.AddTail(95.78);
   m_list.AddTail(90.1);

   POSITION position = m_list.Find(85.26);
   m_list.InsertBefore(position, 200.0);
   m_list.InsertAfter(position, 300.0);

   position = m_list.Find(300.00);
   m_list.SetAt(position, 400.00);

   //iterate the list
   POSITION pos = m_list.GetHeadPosition();
   while (pos) {
      double nData = m_list.GetNext(pos);
      CString strVal;
      strVal.Format(L"%.2f\n", nData);
      m_strText.Append(strVal);
   }

   UpdateData(FALSE);

   return TRUE; // return TRUE unless you set the focus to a control
}

Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả sau. Bây giờ bạn có thể thấy rằng giá trị 300,00 được cập nhật thành 400,00.

Xóa các mục

Để loại bỏ bất kỳ mục cụ thể nào, bạn có thể sử dụng hàm CList :: RemoveAt (). Để xóa tất cả phần tử khỏi danh sách, có thể sử dụng hàm CList :: RemoveAll ().

Hãy để chúng tôi loại bỏ phần tử có giá trị là 95,78.

BOOL CMFCCListDemoDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);              // Set big icon
   SetIcon(m_hIcon, FALSE);             // Set small icon

   // TODO: Add extra initialization here
   CList<double, double>m_list;

   //Add items to the list
   m_list.AddTail(100.75);
   m_list.AddTail(85.26);
   m_list.AddTail(95.78);
   m_list.AddTail(90.1);

   POSITION position = m_list.Find(85.26);
   m_list.InsertBefore(position, 200.0);
   m_list.InsertAfter(position, 300.0);
   
   position = m_list.Find(300.00);
   m_list.SetAt(position, 400.00);

   position = m_list.Find(95.78);
   m_list.RemoveAt(position);

   //iterate the list
   POSITION pos = m_list.GetHeadPosition();
   while (pos) {
      double nData = m_list.GetNext(pos);
      CString strVal;
      strVal.Format(L"%.2f\n", nData);
      m_strText.Append(strVal);
   }
   UpdateData(FALSE);
   
   return TRUE; // return TRUE unless you set the focus to a control
}

Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả sau. Bây giờ bạn có thể thấy rằng giá trị 95,78 không còn nằm trong danh sách.

A databaselà một tập hợp thông tin được tổ chức để có thể dễ dàng truy cập, quản lý và cập nhật. Các lớp cơ sở dữ liệu MFC dựa trên ODBC được thiết kế để cung cấp quyền truy cập vào bất kỳ cơ sở dữ liệu nào có sẵn trình điều khiển ODBC. Bởi vì các lớp sử dụng ODBC, ứng dụng của bạn có thể truy cập dữ liệu ở nhiều định dạng dữ liệu khác nhau và cấu hình cục bộ / từ xa khác nhau.

Bạn không cần phải viết mã trường hợp đặc biệt để xử lý các hệ thống quản lý cơ sở dữ liệu (DBMS) khác nhau. Miễn là người dùng của bạn có trình điều khiển ODBC thích hợp cho dữ liệu họ muốn truy cập, họ có thể sử dụng chương trình của bạn để thao tác dữ liệu trong các bảng được lưu trữ ở đó. Nguồn dữ liệu là một ví dụ cụ thể của dữ liệu được lưu trữ bởi một số hệ quản trị cơ sở dữ liệu (DBMS). Ví dụ bao gồm Microsoft SQL Server, Microsoft Access, v.v.

CDatabase

MFC cung cấp một lớp CDatabasebiểu thị kết nối với nguồn dữ liệu, qua đó bạn có thể thao tác trên nguồn dữ liệu. Bạn có thể có một hoặc nhiều đối tượng CDatabase hoạt động tại một thời điểm trong ứng dụng của mình.

Sr.No. Tên & Mô tả
1

BeginTrans

Bắt đầu một "giao dịch" - một loạt các lệnh gọi có thể đảo ngược đến các chức năng thành viên AddNew, Edit, Delete và Update của lớp CRecordset- trên nguồn dữ liệu được kết nối. Nguồn dữ liệu phải hỗ trợ các giao dịch choBeginTrans để có bất kỳ tác dụng nào.

2

BindParameters

Cho phép bạn ràng buộc các tham số trước khi gọi ExecuteSQL.

3

Cancel

Hủy một hoạt động không đồng bộ hoặc một quy trình từ luồng thứ hai.

4

CanTransact

Trả về nonzero nếu nguồn dữ liệu hỗ trợ các giao dịch.

5

CanUpdate

Trả về nonzero nếu CDatabase đối tượng có thể cập nhật (không chỉ đọc).

6

Close

Đóng kết nối nguồn dữ liệu.

7

CommitTrans

Hoàn tất giao dịch bắt đầu bởi BeginTrans. Các lệnh trong giao dịch làm thay đổi nguồn dữ liệu được thực hiện.

số 8

ExecuteSQL

Thực thi một câu lệnh SQL. Không có bản ghi dữ liệu nào được trả lại.

9

GetBookmarkPersistence

Xác định các hoạt động mà qua đó các dấu trang vẫn tồn tại trên các đối tượng tập bản ghi.

10

GetConnect

Trả về chuỗi kết nối ODBC được sử dụng để kết nối đối tượng CDatabase với nguồn dữ liệu.

11

GetCursorCommitBehavior

Xác định ảnh hưởng của việc thực hiện một giao dịch trên một đối tượng tập bản ghi mở.

12

GetCursorRollbackBehavior

Xác định ảnh hưởng của việc khôi phục giao dịch trên một đối tượng tập bản ghi đang mở.

13

GetDatabaseName

Trả về tên của cơ sở dữ liệu hiện đang được sử dụng.

14

IsOpen

Trả về nonzero nếu CDatabase đối tượng hiện được kết nối với nguồn dữ liệu.

15

OnSetOptions

Được gọi bởi khuôn khổ để thiết lập các tùy chọn kết nối tiêu chuẩn. Việc triển khai mặc định đặt giá trị thời gian chờ truy vấn. Bạn có thể thiết lập các tùy chọn này trước bằng cách gọiSetQueryTimeout.

16

Open

Thiết lập kết nối với nguồn dữ liệu (thông qua trình điều khiển ODBC).

17

OpenEx

Thiết lập kết nối với nguồn dữ liệu (thông qua trình điều khiển ODBC).

18

Rollback

Đảo ngược các thay đổi được thực hiện trong giao dịch hiện tại. Nguồn dữ liệu trở lại trạng thái trước đó, như được xác định trong cuộc gọi BeginTrans, không thay đổi.

19

SetLoginTimeout

Đặt số giây sau đó nỗ lực kết nối nguồn dữ liệu sẽ hết thời gian.

20

SetQueryTimeout

Đặt số giây sau đó các hoạt động truy vấn cơ sở dữ liệu sẽ hết thời gian. Ảnh hưởng đến tất cả các cuộc gọi Open, AddNew, Edit và Delete của tập bản ghi tiếp theo.

Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một ứng dụng dựa trên hộp thoại MFC mới.

Step 1 - Thay đổi chú thích của dòng TODO thành Retrieve Data from Database và kéo một nút và một điều khiển Danh sách như được hiển thị trong ảnh chụp nhanh sau.

Step 2 - Thêm trình xử lý sự kiện nhấp chuột cho nút và biến điều khiển m_ListControl cho Kiểm soát danh sách.

Step 3 - Chúng tôi có cơ sở dữ liệu đơn giản chứa một bảng Nhân viên với một số bản ghi như được hiển thị trong ảnh chụp nhanh sau.

Step 4 - Chúng ta cần đưa vào tệp tiêu đề sau để có thể sử dụng lớp CDatabase.

#include "odbcinst.h"
#include "afxdb.h"

Chèn truy vấn

Câu lệnh SQL INSERT INTO được sử dụng để thêm các hàng dữ liệu mới vào bảng trong cơ sở dữ liệu.

Step 1 - Để thêm các bản ghi mới, chúng ta sẽ sử dụng hàm ExecuteSQL () của lớp CDatabase như trong đoạn mã sau.

CDatabase database;
CString SqlString;
CString strID, strName, strAge;
CString sDriver = L"MICROSOFT ACCESS DRIVER (*.mdb)";
CString sDsn;
CString sFile = L"D:\\Test.mdb";
// You must change above path if it's different
int iRec = 0;

// Build ODBC connection string
sDsn.Format(L"ODBC;DRIVER={%s};DSN='';DBQ=%s", sDriver, sFile);
TRY {
   // Open the database
   database.Open(NULL,false,false,sDsn);

   SqlString = "INSERT INTO Employees (ID,Name,age) VALUES (5,'Sanjay',69)";
   database.ExecuteSQL(SqlString);
   // Close the database
   database.Close();
}CATCH(CDBException, e) {
   // If a database exception occured, show error msg
   AfxMessageBox(L"Database error: " + e→m_strError);
}
END_CATCH;

Step 2 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy rằng một bản ghi mới được thêm vào cơ sở dữ liệu của bạn.

Truy xuất bản ghi

Để truy xuất bảng trên trong ứng dụng MFC, chúng ta thực hiện các thao tác liên quan đến cơ sở dữ liệu trong trình xử lý sự kiện nút như được hiển thị trong các bước sau.

Step 1- Để sử dụng CDatabase, hãy xây dựng một đối tượng CDatabase và gọi hàm Open () của nó. Điều này sẽ mở kết nối.

Step 2 - Xây dựng các đối tượng CRecordset để hoạt động trên nguồn dữ liệu được kết nối, chuyển phương thức khởi tạo tập bản ghi một con trỏ tới đối tượng CDatabase của bạn.

Step 3 - Sau khi sử dụng kết nối, gọi hàm Close và hủy đối tượng CDatabase.

void CMFCDatabaseDemoDlg::OnBnClickedButtonRead() {
   // TODO: Add your control notification handler code here
   CDatabase database;
   CString SqlString;
   CString strID, strName, strAge;
   CString sDriver = "MICROSOFT ACCESS DRIVER (*.mdb)";
   CString sFile = L"D:\\Test.mdb";
   // You must change above path if it's different
   int iRec = 0;

   // Build ODBC connection string
   sDsn.Format("ODBC;DRIVER={%s};DSN='';DBQ=%s",sDriver,sFile);
   TRY {
      // Open the database
      database.Open(NULL,false,false,sDsn);

      // Allocate the recordset
      CRecordset recset( &database );

      // Build the SQL statement
      SqlString = "SELECT ID, Name, Age " "FROM Employees";

      // Execute the query
	  
      recset.Open(CRecordset::forwardOnly,SqlString,CRecordset::readOnly);
      // Reset List control if there is any data
      ResetListControl();
      // populate Grids
      ListView_SetExtendedListViewStyle(m_ListControl,LVS_EX_GRIDLINES);

      // Column width and heading
      m_ListControl.InsertColumn(0,"Emp ID",LVCFMT_LEFT,-1,0);
      m_ListControl.InsertColumn(1,"Name",LVCFMT_LEFT,-1,1);
      m_ListControl.InsertColumn(2, "Age", LVCFMT_LEFT, -1, 1);
      m_ListControl.SetColumnWidth(0, 120);
      m_ListControl.SetColumnWidth(1, 200);
      m_ListControl.SetColumnWidth(2, 200);

      // Loop through each record
      while( !recset.IsEOF() ) {
         // Copy each column into a variable
         recset.GetFieldValue("ID",strID);
         recset.GetFieldValue("Name",strName);
         recset.GetFieldValue("Age", strAge);

         // Insert values into the list control
         iRec = m_ListControl.InsertItem(0,strID,0);
         m_ListControl.SetItemText(0,1,strName);
         m_ListControl.SetItemText(0, 2, strAge);

         // goto next record
         recset.MoveNext();
      }
      // Close the database
      database.Close();
   }CATCH(CDBException, e) {
      // If a database exception occured, show error msg
      AfxMessageBox("Database error: "+e→m_strError);
   }
   END_CATCH; 
}

// Reset List control
void CMFCDatabaseDemoDlg::ResetListControl() {
   m_ListControl.DeleteAllItems();
   int iNbrOfColumns;
   CHeaderCtrl* pHeader = (CHeaderCtrl*)m_ListControl.GetDlgItem(0);
   if (pHeader) {
      iNbrOfColumns = pHeader→GetItemCount();
   }
   for (int i = iNbrOfColumns; i >= 0; i--) {
      m_ListControl.DeleteColumn(i);
   }
}

Step 4 - Đây là tệp tiêu đề.

// MFCDatabaseDemoDlg.h : header file
//

#pragma once
#include "afxcmn.h"


// CMFCDatabaseDemoDlg dialog
class CMFCDatabaseDemoDlg : public CDialogEx {
   // Construction
   public:
      CMFCDatabaseDemoDlg(CWnd* pParent = NULL);    // standard constructor

   // Dialog Data
   #ifdef AFX_DESIGN_TIME
      enum { IDD = IDD_MFCDATABASEDEMO_DIALOG };
   #endif

   protected:
      virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
      void ResetListControl();

   // Implementation
   protected:
      HICON m_hIcon;

      // Generated message map functions
      virtual BOOL OnInitDialog();
      afx_msg void OnPaint();
      afx_msg HCURSOR OnQueryDragIcon();
      DECLARE_MESSAGE_MAP()
   public:
      CListCtrl m_ListControl;
      afx_msg void OnBnClickedButtonRead();
};

Step 5 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 6- Nhấn nút Đọc để thực hiện các thao tác với cơ sở dữ liệu. Nó sẽ truy xuất bảng Nhân viên.

Cập nhật bản ghi

Truy vấn CẬP NHẬT SQL được sử dụng để sửa đổi các bản ghi hiện có trong bảng. Bạn có thể sử dụng mệnh đề WHERE với truy vấn UPDATE để cập nhật các hàng đã chọn nếu không tất cả các hàng sẽ bị ảnh hưởng.

Step 1 - Chúng ta hãy xem xét một ví dụ đơn giản bằng cách cập nhật Độ tuổi mà ID bằng 5.

SqlString = L"UPDATE Employees SET Age = 59 WHERE ID = 5;";
database.ExecuteSQL(SqlString);

Step 2 - Đây là mã hoàn chỉnh của sự kiện bấm nút.

void CMFCDatabaseDemoDlg::OnBnClickedButtonRead() {
   // TODO: Add your control notification handler code here
   CDatabase database;
   CString SqlString;
   CString strID, strName, strAge;
   CString sDriver = L"MICROSOFT ACCESS DRIVER (*.mdb)";
   CString sDsn;
   CString sFile =
      L"C:\\Users\\Muhammad.Waqas\\Downloads\\Compressed\\ReadDB_demo\\Test.mdb";
   // You must change above path if it's different
   int iRec = 0;

   // Build ODBC connection string
   sDsn.Format(L"ODBC;DRIVER={%s};DSN='';DBQ=%s", sDriver, sFile);
   TRY {
      // Open the database
      database.Open(NULL,false,false,sDsn);

      // Allocate the recordset
      CRecordset recset(&database);

      SqlString = L"UPDATE Employees SET Age = 59 WHERE ID = 5;";

      database.ExecuteSQL(SqlString);

      SqlString = "SELECT ID, Name, Age FROM Employees";

      // Build the SQL statement
      SqlString = "SELECT ID, Name, Age FROM Employees";

      // Execute the query
      recset.Open(CRecordset::forwardOnly,SqlString,CRecordset::readOnly);

      // Reset List control if there is any data
      ResetListControl();
      // populate Grids
      ListView_SetExtendedListViewStyle(m_listCtrl,LVS_EX_GRIDLINES);

      // Column width and heading
      m_listCtrl.InsertColumn(0,L"Emp ID",LVCFMT_LEFT,-1,0);
      m_listCtrl.InsertColumn(1,L"Name",LVCFMT_LEFT,-1,1);
      m_listCtrl.InsertColumn(2, L"Age", LVCFMT_LEFT, -1, 1);
      m_listCtrl.SetColumnWidth(0, 120);
      m_listCtrl.SetColumnWidth(1, 200);
      m_listCtrl.SetColumnWidth(2, 200);

      // Loop through each record
      while (!recset.IsEOF()) {
         // Copy each column into a variable
         recset.GetFieldValue(L"ID",strID);
         recset.GetFieldValue(L"Name",strName);
         recset.GetFieldValue(L"Age", strAge);

         // Insert values into the list control
         iRec = m_listCtrl.InsertItem(0,strID,0);
         m_listCtrl.SetItemText(0,1,strName);
         m_listCtrl.SetItemText(0, 2, strAge);

         // goto next record
         recset.MoveNext();
      }

      // Close the database
      database.Close();
   }CATCH(CDBException, e) {
      // If a database exception occured, show error msg
      AfxMessageBox(L"Database error: " + e→m_strError);
   }
   END_CATCH;
}

Step 3 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 4- Nhấn nút Đọc để thực hiện các thao tác với cơ sở dữ liệu. Nó sẽ truy xuất bảng Nhân viên sau.

Step 5 - Bây giờ bạn có thể thấy rằng tuổi được cập nhật từ 69 thành 59.

Xóa hồ sơ

Truy vấn SQL DELETE được sử dụng để xóa các bản ghi hiện có khỏi bảng. Bạn có thể sử dụng mệnh đề WHERE với truy vấn DELETE để xóa các hàng đã chọn, nếu không tất cả các bản ghi sẽ bị xóa.

Step 1 - Chúng ta hãy xem xét một ví dụ đơn giản bằng cách xóa bản ghi có ID bằng 3.

SqlString = L"DELETE FROM Employees WHERE ID = 3;";

database.ExecuteSQL(SqlString);

Step 2 - Đây là mã hoàn chỉnh của sự kiện bấm nút.

void CMFCDatabaseDemoDlg::OnBnClickedButtonRead() {
   // TODO: Add your control notification handler code here
   CDatabase database;
   CString SqlString;
   CString strID, strName, strAge;
   CString sDriver = L"MICROSOFT ACCESS DRIVER (*.mdb)";
   CString sDsn;
   CString sFile =
       L"C:\\Users\\Muhammad.Waqas\\Downloads\\Compressed\\ReadDB_demo\\Test.mdb";

   // You must change above path if it's different
   int iRec = 0;

   // Build ODBC connection string
   sDsn.Format(L"ODBC;DRIVER={%s};DSN='';DBQ=%s", sDriver, sFile);
   TRY {
      // Open the database
      database.Open(NULL,false,false,sDsn);

      // Allocate the recordset
      CRecordset recset(&database);

      SqlString = L"DELETE FROM Employees WHERE ID = 3;";

      database.ExecuteSQL(SqlString);

      SqlString = "SELECT ID, Name, Age FROM Employees";

      // Build the SQL statement
      SqlString = "SELECT ID, Name, Age FROM Employees";

      // Execute the query
      recset.Open(CRecordset::forwardOnly,SqlString,CRecordset::readOnly);

      // Reset List control if there is any data
      ResetListControl();
      // populate Grids
      ListView_SetExtendedListViewStyle(m_listCtrl,LVS_EX_GRIDLINES);
      // Column width and heading
      m_listCtrl.InsertColumn(0,L"Emp ID",LVCFMT_LEFT,-1,0);
      m_listCtrl.InsertColumn(1,L"Name",LVCFMT_LEFT,-1,1);
      m_listCtrl.InsertColumn(2, L"Age", LVCFMT_LEFT, -1, 1);
      m_listCtrl.SetColumnWidth(0, 120);
      m_listCtrl.SetColumnWidth(1, 200);
      m_listCtrl.SetColumnWidth(2, 200);

      // Loop through each record
      while (!recset.IsEOF()) {
         // Copy each column into a variable
         recset.GetFieldValue(L"ID",strID);
         recset.GetFieldValue(L"Name",strName);
         recset.GetFieldValue(L"Age", strAge);

         // Insert values into the list control
         iRec = m_listCtrl.InsertItem(0,strID,0);
         m_listCtrl.SetItemText(0,1,strName);
         m_listCtrl.SetItemText(0, 2, strAge);

         // goto next record
         recset.MoveNext();
      }
      // Close the database
      database.Close();
   }CATCH(CDBException, e) {
      // If a database exception occured, show error msg
      AfxMessageBox(L"Database error: " + e→m_strError);
   }
   END_CATCH;
}

Step 3 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 4- Nhấn nút Đọc để thực hiện các thao tác với cơ sở dữ liệu. Nó sẽ truy xuất bảng Nhân viên.

Serializationlà quá trình ghi hoặc đọc một đối tượng đến hoặc từ một phương tiện lưu trữ liên tục như tệp đĩa. Tuần tự hóa là lý tưởng cho các trường hợp muốn duy trì trạng thái của dữ liệu có cấu trúc (chẳng hạn như các lớp hoặc cấu trúc C ++) trong hoặc sau khi thực hiện một chương trình.

Khi thực hiện xử lý tệp, các giá trị thường có kiểu nguyên thủy (char, short, int, float hoặc double). Theo cách tương tự, chúng ta có thể lưu riêng lẻ nhiều giá trị tại một thời điểm. Kỹ thuật này không bao gồm một đối tượng được tạo từ (như một biến của) một lớp.

Thư viện MFC có mức độ hỗ trợ cao cho việc tuần tự hóa. Nó bắt đầu với lớp CObject là lớp tổ tiên của hầu hết các lớp MFC, được trang bị hàm thành viên Serialize ().

Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một dự án MFC mới.

Step 1 - Loại bỏ dòng TODO và thiết kế hộp thoại của bạn như trong ảnh chụp nhanh sau.

Step 2- Thêm các biến giá trị cho tất cả các điều khiển chỉnh sửa. Đối với Emp ID và Age được đề cập, loại giá trị là một số nguyên như được hiển thị trong ảnh chụp nhanh sau.

Step 3 - Thêm trình xử lý sự kiện cho cả hai nút.

Step 4- Bây giờ chúng ta hãy thêm một lớp Nhân viên đơn giản, mà chúng ta cần phải tuần tự hóa. Đây là phần khai báo của lớp Employee trong tệp tiêu đề.

class CEmployee : public CObject {
   public:
      int empID;
      CString empName;
      int age;
      CEmployee(void);
      ~CEmployee(void);
   private:

   public:
      void Serialize(CArchive& ar);
      DECLARE_SERIAL(CEmployee);
};

Step 5 - Đây là định nghĩa của lớp Nhân viên trong tệp nguồn (* .cpp).

IMPLEMENT_SERIAL(CEmployee, CObject, 0)
CEmployee::CEmployee(void) {

}

CEmployee::~CEmployee(void) {

}

void CEmployee::Serialize(CArchive& ar) {
   CObject::Serialize(ar);

   if (ar.IsStoring())
      ar << empID << empName << age;
   else
      ar >> empID >> empName >> age;
}

Step 6 - Đây là phần thực hiện xử lý sự kiện nút Lưu.

void CMFCSerializationDlg::OnBnClickedButtonSave() {
   // TODO: Add your control notification handler code here
   UpdateData(TRUE);
   CEmployee employee;
   CFile file;
   file.Open(L"EmployeeInfo.hse", CFile::modeCreate | CFile::modeWrite);
   CArchive ar(&file, CArchive::store);
   employee.empID = m_id;
   employee.empName = m_strName;
   employee.age = m_age;
   employee.Serialize(ar);
   ar.Close();
}

Step 7 - Đây là phần thực hiện của Open button event handler.

void CMFCSerializationDlg::OnBnClickedButtonOpen() {
   // TODO: Add your control notification handler code here
   UpdateData(TRUE);

   CFile file;

   file.Open(L"EmployeeInfo.hse", CFile::modeRead);
   CArchive ar(&file, CArchive::load);
   CEmployee employee;

   employee.Serialize(ar);

   m_id = employee.empID;
   m_strName = employee.empName;
   m_age = employee.age;
   ar.Close();
   file.Close();

   UpdateData(FALSE);
}

Step 8 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 9 - Nhập thông tin vào tất cả các trường và nhấp vào Lưu và đóng chương trình này.

Step 10- Nó sẽ lưu dữ liệu. Chạy lại ứng dụng và nhấp vào mở. Nó sẽ tải thông tin Nhân viên.

Thư viện Microsoft Foundation Class (MFC) cung cấp hỗ trợ cho các ứng dụng đa luồng. Một luồng là một đường dẫn thực thi trong một tiến trình. Khi bạn khởi động Notepad, hệ điều hành sẽ tạo một quy trình và bắt đầu thực thi luồng chính của quy trình đó. Khi luồng này kết thúc, quá trình cũng vậy.

Bạn có thể tạo các chuỗi bổ sung trong ứng dụng của mình nếu bạn muốn. Tất cả các luồng trong ứng dụng MFC được biểu diễn bằng các đối tượng CWinThread. Trong hầu hết các tình huống, bạn thậm chí không cần phải tạo các đối tượng này một cách rõ ràng; thay vào đó hãy gọi hàm trợ giúp khung AfxBeginThread, hàm này tạo đối tượng CWinThread cho bạn.

Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một ứng dụng dựa trên hộp thoại MFC mới.

Step 1 - Thay đổi Chú thích và ID của Điều khiển tĩnh thành Click on Start Thread buttonIDC_STATIC_TEXT tương ứng.

Step 2 - Kéo hai nút và thêm trình xử lý sự kiện nhấp chuột cho các nút này.

Step 3 - Thêm biến điều khiển để điều khiển văn bản tĩnh.

Step 4 - Bây giờ hãy thêm ba biến toàn cục sau vào đầu tệp CMFCMultithreadingDlg.cpp.

int currValue;
int maxValue;
BOOL stopNow;

Step 5 - Thêm thông báo WM_TIMER trong lớp CMFCMultithreadingDlg.

Đây là việc triển khai OnTimer ()

void CMFCMultithreadingDlg::OnTimer(UINT_PTR nIDEvent) {
   // TODO: Add your message handler code here and/or call default
   CString sStatusMsg;
   sStatusMsg.Format(L"Running: %d", currValue);
   m_ctrlStatus.SetWindowText(sStatusMsg);

   CDialogEx::OnTimer(nIDEvent);
}

Step 6 - Bây giờ thêm một hàm mẫu để sử dụng trong AfxBeginThread trong lớp CMFCMultithreadingDlg.

UINT MyThreadProc(LPVOID Param) {
   while (!stopNow && (currValue < maxValue)) {
      currValue++;
      Sleep(50);     // would do some work here
   }
   
   return TRUE;
}

Step 7 - Đây là việc thực hiện xử lý sự kiện cho nút Start Thread, nút này sẽ bắt đầu luồng.

void CMFCMultithreadingDlg::OnBnClickedButtonStart() {
   // TODO: Add your control notification handler code here
   currValue = 0;
   maxValue = 5000;
   stopNow = 0;
   m_ctrlStatus.SetWindowText(L"Starting...");
   SetTimer(1234, 333, 0); // 3 times per second

   AfxBeginThread(MyThreadProc, 0); // <<== START THE THREAD
}

Step 8 - Đây là việc triển khai trình xử lý sự kiện cho nút Stop Thread, nút này sẽ dừng luồng.

void CMFCMultithreadingDlg::OnBnClickedButtonStop() {
   
   // TODO: Add your control notification handler code here
   stopNow = TRUE;
   KillTimer(1234);
   m_ctrlStatus.SetWindowText(L"Stopped");
}

Step 9 - Đây là tập tin nguồn hoàn chỉnh.

// MFCMultithreadingDlg.cpp : implementation file
//

#include "stdafx.h"
#include "MFCMultithreading.h"
#include "MFCMultithreadingDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CMFCMultithreadingDlg dialog

int currValue;
int maxValue;
BOOL stopNow;

CMFCMultithreadingDlg::CMFCMultithreadingDlg(CWnd* pParent /* = NULL*/)
   : CDialogEx(IDD_MFCMULTITHREADING_DIALOG, pParent) {
   m_hIcon = AfxGetApp() -> LoadIcon(IDR_MAINFRAME);
}
void CMFCMultithreadingDlg::DoDataExchange(CDataExchange* pDX) {
   CDialogEx::DoDataExchange(pDX);
   DDX_Control(pDX, IDC_STATIC_TEXT, m_ctrlStatus);
}

BEGIN_MESSAGE_MAP(CMFCMultithreadingDlg, CDialogEx)
   ON_WM_PAINT()
   ON_WM_QUERYDRAGICON()
   ON_BN_CLICKED(IDC_BUTTON_START,
      &CMFCMultithreadingDlg::OnBnClickedButtonStart)
   ON_WM_TIMER()
   ON_BN_CLICKED(IDC_BUTTON_STOP,
      &CMFCMultithreadingDlg::OnBnClickedButtonStop)
END_MESSAGE_MAP()

// CMFCMultithreadingDlg message handlers

BOOL CMFCMultithreadingDlg::OnInitDialog() {
   CDialogEx::OnInitDialog();

   // Set the icon for this dialog. The framework does this automatically
   // when the application's main window is not a dialog
   SetIcon(m_hIcon, TRUE);        // Set big icon
   SetIcon(m_hIcon, FALSE);       // Set small icon

   // TODO: Add extra initialization here

   return TRUE; // return TRUE unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.

void CMFCMultithreadingDlg::OnPaint() {
   if (IsIconic()) {
      CPaintDC dc(this); // device context for painting
      SendMessage(WM_ICONERASEBKGND,
         reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
			
      // Center icon in client rectangle
      int cxIcon = GetSystemMetrics(SM_CXICON);
      int cyIcon = GetSystemMetrics(SM_CYICON);
      CRect rect;
      GetClientRect(&rect);
      int x = (rect.Width() - cxIcon + 1) / 2;
      int y = (rect.Height() - cyIcon + 1) / 2;

      // Draw the icon
      dc.DrawIcon(x, y, m_hIcon);
   }else {
      CDialogEx::OnPaint();
   }
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMFCMultithreadingDlg::OnQueryDragIcon() {
   return static_cast<HCURSOR>(m_hIcon);
}

UINT /*CThreadDlg::*/MyThreadProc(LPVOID Param) //Sample function for using in
AfxBeginThread {
   while (!stopNow && (currValue < maxValue)) {
      currValue++;
      Sleep(50); // would do some work here
   }
   return TRUE;
}
void CMFCMultithreadingDlg::OnBnClickedButtonStart() {
   // TODO: Add your control notification handler code here
   currValue = 0;
   maxValue = 5000;
   stopNow = 0;
   m_ctrlStatus.SetWindowText(L"Starting...");
   SetTimer(1234, 333, 0); // 3 times per second

   AfxBeginThread(MyThreadProc, 0); // <<== START THE THREAD
}

void CMFCMultithreadingDlg::OnTimer(UINT_PTR nIDEvent) {
   // TODO: Add your message handler code here and/or call default
   CString sStatusMsg;
   sStatusMsg.Format(L"Running: %d", currValue);
   m_ctrlStatus.SetWindowText(sStatusMsg);

   CDialogEx::OnTimer(nIDEvent);
}

void CMFCMultithreadingDlg::OnBnClickedButtonStop() {
   // TODO: Add your control notification handler code here
   stopNow = TRUE;
   KillTimer(1234);
   m_ctrlStatus.SetWindowText(L"Stopped");
}

Step 10 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 11 - Bây giờ bấm vào nút Start Thread.

Step 12- Nhấp vào nút Stop Thread. Nó sẽ dừng luồng.

Microsoft cung cấp nhiều API để lập trình cả ứng dụng máy khách và máy chủ. Nhiều ứng dụng mới đang được viết cho Internet, và khi công nghệ, khả năng của trình duyệt và các tùy chọn bảo mật thay đổi, các loại ứng dụng mới sẽ được viết. Ứng dụng tùy chỉnh của bạn có thể truy xuất thông tin và cung cấp dữ liệu trên Internet.

MFC cung cấp một lớp CSocket để viết các chương trình truyền thông mạng với Windows Sockets.

Đây là danh sách các phương thức trong lớp CSocket.

Sr.No. Tên & Mô tả
1

Attach

Gắn một tay cầm SOCKET vào một đối tượng CSocket.

2

CancelBlockingCall

Hủy cuộc gọi chặn hiện đang diễn ra.

3

Create

Tạo một ổ cắm.

4

FromHandle

Trả về một con trỏ đến một đối tượng CSocket, được cung cấp bởi một tay cầm SOCKET.

5

IsBlocking

Xác định xem có đang thực hiện một cuộc gọi chặn hay không.

Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một ứng dụng MFS SDI.

Step 1 - Nhập MFCServer vào trường tên và nhấp OK.

Step 2 - Trên tab Tính năng nâng cao, chọn tùy chọn ổ cắm Windows.

Step 3 - Sau khi dự án được tạo, hãy thêm một CServerSocket lớp MFC mới.

Step 4 - Chọn CSocket làm lớp cơ sở và nhấp vào Kết thúc.

Step 5 - Thêm thêm CReceivingSocket lớp MFC.

Step 6 - CRecevingSocket sẽ nhận tin nhắn đến từ máy khách.

Trong CMFCServerApp, tệp tiêu đề bao gồm các tệp sau:

#include "ServerSocket.h"
#include "MFCServerView.h"

Step 7 - Thêm hai biến lớp sau trong lớp CMFCServerApp.

CServerSocket m_serverSocket;
CMFCServerView m_pServerView;

Step 8 - Trong phương thức CMFCServerApp :: InitInstance (), tạo socket và chỉ định port rồi gọi phương thức Listen như hình bên dưới.

m_serverSocket.Create(6666);
m_serverSocket.Listen();

Step 9 - Đưa tệp tiêu đề sau vào tệp tiêu đề CMFCServerView.

#include "MFCServerDoc.h"

Step 10 - Ghi đè hàm OnAccept khỏi lớp Socket.

Step 11- Chọn CServerSocket trong chế độ xem lớp và biểu tượng được tô sáng trong cửa sổ Thuộc tính. Bây giờ, Thêm OnAccept. Đây là việc thực hiện chức năng OnAccept.

void CServerSocket::OnAccept(int nErrorCode) {

   // TODO: Add your specialized code here and/or call the base class
   AfxMessageBox(L"Connection accepted");
   CSocket::OnAccept(nErrorCode);
}

Step 12 - Thêm hàm OnReceive ().

void CServerSocket::OnReceive(int nErrorCode) { 
   
   // TODO: Add your specialized code here and/or call the base class
   AfxMessageBox(L"Data Received");
   CSocket::OnReceive(nErrorCode);
}

Step 13 - Thêm hàm OnReceive () trong lớp CReceivingSocket.

Nhấp chuột phải vào lớp CMFCServerView trong trình khám phá giải pháp và chọn Thêm → AddFunction.

Step 14 - Nhập các thông tin đã đề cập ở trên và nhấn hoàn tất.

Step 15 - Thêm biến CStringArray sau trong tệp tiêu đề CMFCServerView.

CStringArray m_msgArray;

Step 16 - Đây là phần thực hiện của hàm AddMsg ().

void CMFCServerView::AddMsg(CString message) {

   m_msgArray.Add(message);
   Invalidate();
}

Step 17 - Cập nhật hàm tạo như được hiển thị trong đoạn mã sau.

CMFCServerView::CMFCServerView() {

   ((CMFCServerApp*)AfxGetApp()) -> m_pServerView = this;
}

Step 18 - Đây là phần thực hiện của hàm OnDraw () hiển thị thông báo.

void CMFCServerView::OnDraw(CDC* pDC) {

   int y = 100;
   for (int i = 0; m_msgArray.GetSize(); i++) {
   
      pDC->TextOut(100, y, m_msgArray.GetAt(i));
      y += 50;
   }
   CMFCServerDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;

   // TODO: add draw code for native data here
}

Step 19- Hiện tại phía máy chủ đã hoàn tất. Nó sẽ nhận được tin nhắn từ khách hàng.

Tạo ứng dụng phía máy khách

Step 1 - Hãy để chúng tôi tạo một ứng dụng dựa trên hộp thoại MFC mới cho ứng dụng phía máy khách.

Step 2 - Trên tab Advanced Features, đánh dấu vào tùy chọn Windows sockets như hình trên.

Step 3 - Sau khi dự án được tạo, hãy thiết kế hộp thoại của bạn như thể hiện trong ảnh chụp nhanh sau.

Step 4 - Thêm trình xử lý sự kiện cho các nút Kết nối và Gửi.

Step 5- Thêm các biến giá trị cho cả ba điều khiển chỉnh sửa. Đối với điều khiển chỉnh sửa cổng, hãy chọn loại biến UINT.

Step 6 - Thêm lớp MFC để kết nối và gửi tin nhắn.

Step 7- Đưa tệp tiêu đề của lớp CClientSocket vào tệp tiêu đề của lớp CMFCClientDemoApp và thêm biến lớp. Tương tự, hãy thêm biến lớp trong tệp tiêu đề CMFCClientDemoDlg.

CClientSocket m_clientSocket;

Step 8 - Đây là phần triển khai của bộ xử lý sự kiện nút Connect.

void CMFCClientDemoDlg::OnBnClickedButtonConnect() {

   // TODO: Add your control notification handler code here
   UpdateData(TRUE);
   m_clientSocket.Create();
   if (m_clientSocket.Connect(m_ipAddress, m_port)) {
      AfxMessageBox(L"Connection Successfull");
   }else {
      AfxMessageBox(L"Connection Failed");
   }
   DWORD error = GetLastError();
}

Step 9 - Đây là phần thực hiện của bộ xử lý sự kiện nút Gửi.

void CMFCClientDemoDlg::OnBnClickedButtonSend() {

   // TODO: Add your control notification handler code here
   UpdateData(TRUE);
   if (m_clientSocket.Send(m_message.GetBuffer(m_message.GetLength()), m_message.GetLength())) {
   
   }else {
      AfxMessageBox(L"Failed to send message");
   }
}

Step 10- Đầu tiên chạy ứng dụng Máy chủ và sau đó là ứng dụng máy khách. Nhập ip và cổng của máy chủ cục bộ và nhấp vào Kết nối.

Step 11 - Bây giờ bạn sẽ thấy thông báo ở phía Server như trong ảnh chụp sau.

Windows cung cấp nhiều công cụ vẽ khác nhau để sử dụng trong các ngữ cảnh thiết bị. Nó cung cấp bút để vẽ đường, bút vẽ để tô màu nội thất và phông chữ để vẽ văn bản. MFC cung cấp các lớp đối tượng đồ họa tương đương với các công cụ vẽ trong Windows.

Đang vẽ

Bối cảnh thiết bị là cấu trúc dữ liệu Windows chứa thông tin về các thuộc tính bản vẽ của thiết bị như màn hình hoặc máy in. Tất cả các lệnh gọi bản vẽ được thực hiện thông qua đối tượng ngữ cảnh thiết bị, đối tượng này đóng gói các API Windows để vẽ đường thẳng, hình dạng và văn bản.

Các ngữ cảnh thiết bị cho phép vẽ độc lập với thiết bị trong Windows. Các ngữ cảnh thiết bị có thể được sử dụng để vẽ ra màn hình, tới máy in hoặc vào một siêu tệp.

CDClà lớp cơ bản nhất để vẽ trong MFC. Đối tượng CDC cung cấp các chức năng thành viên để thực hiện các bước vẽ cơ bản, cũng như các chức năng thành viên để làm việc với bối cảnh hiển thị được liên kết với vùng khách của cửa sổ.

Sơ không. Tên & Mô tả
1

AbortDoc

Chấm dứt công việc in hiện tại, xóa mọi thứ ứng dụng đã ghi vào thiết bị kể từ lần gọi cuối cùng của StartDoc chức năng thành viên.

2

AbortPath

Đóng và loại bỏ bất kỳ đường dẫn nào trong ngữ cảnh thiết bị.

3

AddMetaFileComment

Sao chép nhận xét từ bộ đệm vào một siêu tệp định dạng nâng cao được chỉ định.

4

AlphaBlend

Hiển thị các bitmap có pixel trong suốt hoặc bán trong suốt.

5

AngleArc

Vẽ một đoạn thẳng và một cung, và di chuyển vị trí hiện tại đến điểm kết thúc của cung.

6

Arc

Vẽ một cung hình elip.

7

ArcTo

Vẽ một cung hình elip. Chức năng này tương tự như Arc, ngoại trừ vị trí hiện tại được cập nhật.

số 8

Attach

Đính kèm ngữ cảnh thiết bị Windows vào đối tượng CDC này.

9

BeginPath

Mở dấu ngoặc vuông đường dẫn trong ngữ cảnh thiết bị.

10

BitBlt

Sao chép một bitmap từ một ngữ cảnh thiết bị cụ thể.

11

Chord

Vẽ một hợp âm (một hình khép kín được giới hạn bởi giao điểm của một hình elip và một đoạn thẳng).

12

CloseFigure

Đóng một hình mở trong một đường dẫn.

13

CreateCompatibleDC

Tạo ngữ cảnh thiết bị nhớ tương thích với ngữ cảnh thiết bị khác. Bạn có thể sử dụng nó để chuẩn bị hình ảnh trong bộ nhớ.

14

CreateDC

Tạo bối cảnh thiết bị cho một thiết bị cụ thể.

15

CreateIC

Tạo bối cảnh thông tin cho một thiết bị cụ thể. Điều này cung cấp một cách nhanh chóng để nhận thông tin về thiết bị mà không cần tạo bối cảnh thiết bị.

16

DeleteDC

Xóa bối cảnh thiết bị Windows được liên kết với đối tượng CDC này.

17

DeleteTempMap

Được gọi bởi CWinApptrình xử lý thời gian nhàn rỗi để xóa bất kỳ đối tượng CDC tạm thời nào được tạo bởi FromHandle. Cũng tách bối cảnh thiết bị.

18

Detach

Tách bối cảnh thiết bị Windows khỏi đối tượng CDC này.

19

DPtoHIMETRIC

Chuyển đổi các đơn vị thiết bị thành HIMETRIC các đơn vị.

20

DPtoLP

Chuyển đổi đơn vị thiết bị thành đơn vị logic.

21

Draw3dRect

Vẽ một hình chữ nhật ba chiều.

22

DrawDragRect

Xóa và vẽ lại một hình chữ nhật khi nó được kéo.

23

DrawEdge

Vẽ các cạnh của hình chữ nhật.

24

DrawEscape

Truy cập khả năng vẽ của màn hình video không có sẵn trực tiếp thông qua giao diện thiết bị đồ họa (GDI).

25

DrawFocusRect

Vẽ một hình chữ nhật theo kiểu được sử dụng để biểu thị tiêu điểm.

26

DrawFrameControl

Vẽ điều khiển khung.

27

DrawIcon

Vẽ một biểu tượng.

28

DrawState

Hiển thị hình ảnh và áp dụng hiệu ứng hình ảnh để biểu thị trạng thái.

29

DrawText

Vẽ văn bản được định dạng trong hình chữ nhật được chỉ định.

30

DrawTextEx

Vẽ văn bản được định dạng trong hình chữ nhật được chỉ định bằng cách sử dụng các định dạng bổ sung.

31

Ellipse

Vẽ một hình elip.

32

EndDoc

Kết thúc lệnh in được bắt đầu bởi chức năng thành viên StartDoc.

33

EndPage

Thông báo cho trình điều khiển thiết bị rằng một trang đang kết thúc.

34

EndPath

Đóng một dấu ngoặc vuông và chọn đường dẫn được xác định bởi dấu ngoặc vào ngữ cảnh thiết bị.

35

EnumObjects

Liệt kê các bút và bút vẽ có sẵn trong ngữ cảnh thiết bị.

36

Escape

Cho phép ứng dụng truy cập các tiện ích không có sẵn trực tiếp từ một thiết bị cụ thể thông qua GDI. Đồng thời cho phép truy cập vào các chức năng thoát của Windows. Các cuộc gọi thoát do một ứng dụng thực hiện sẽ được dịch và gửi tới trình điều khiển thiết bị.

37

ExcludeClipRect

Tạo vùng cắt mới bao gồm vùng cắt hiện có trừ đi hình chữ nhật được chỉ định.

38

ExcludeUpdateRgn

Ngăn việc vẽ trong các vùng không hợp lệ của cửa sổ bằng cách loại trừ vùng đã cập nhật trong cửa sổ khỏi vùng cắt.

39

ExtFloodFill

Điền vào một khu vực bằng bàn chải hiện tại. Cung cấp tính linh hoạt hơnFloodFill chức năng thành viên.

40

ExtTextOut

Viết một chuỗi ký tự trong một vùng hình chữ nhật bằng cách sử dụng phông chữ hiện được chọn.

41

FillPath

Đóng bất kỳ số liệu nào đang mở trong đường dẫn hiện tại và lấp đầy phần bên trong của đường dẫn bằng cách sử dụng bàn chải hiện tại và chế độ điền đa giác.

42

FillRect

Điền vào một hình chữ nhật nhất định bằng cách sử dụng một bàn chải cụ thể.

43

FillRgn

Điền vào một khu vực cụ thể bằng bàn chải được chỉ định.

44

FillSolidRect

Tô màu một hình chữ nhật.

45

FlattenPath

Chuyển đổi bất kỳ đường cong nào trong đường dẫn đã chọn thành bối cảnh thiết bị hiện tại và biến mỗi đường cong thành một chuỗi đường.

46

FloodFill

Điền vào một khu vực bằng bàn chải hiện tại.

47

FrameRect

Vẽ một đường viền xung quanh một hình chữ nhật.

48

FrameRgn

Vẽ đường viền xung quanh một vùng cụ thể bằng bút vẽ.

49

FromHandle

Trả về một con trỏ đến một đối tượng CDC khi được cung cấp một xử lý cho ngữ cảnh thiết bị. Nếu một đối tượng CDC không được gắn vào tay cầm, một đối tượng CDC tạm thời sẽ được tạo và gắn vào.

50

GetArcDirection

Trả về hướng vòng cung hiện tại cho ngữ cảnh thiết bị.

51

GetAspectRatioFilter

Truy xuất cài đặt cho bộ lọc tỷ lệ khung hình hiện tại.

52

GetBkColor

Lấy màu nền hiện tại.

53

GetBkMode

Truy xuất chế độ nền.

54

GetBoundsRect

Trả về hình chữ nhật giới hạn tích lũy hiện tại cho ngữ cảnh thiết bị được chỉ định.

55

GetBrushOrg

Truy xuất nguồn gốc của bàn chải hiện tại.

56

GetCharABCWidths

Lấy độ rộng, theo đơn vị logic, của các ký tự liên tiếp trong một phạm vi nhất định từ phông chữ hiện tại.

57

GetCharABCWidthsI

Lấy độ rộng, theo đơn vị logic, của các chỉ số glyph liên tiếp trong một phạm vi được chỉ định từ phông chữ TrueType hiện tại.

58

GetCharacterPlacement

Lấy nhiều loại thông tin khác nhau trên một chuỗi ký tự.

59

GetCharWidth

Lấy độ rộng phân số của các ký tự liên tiếp trong một phạm vi nhất định từ phông chữ hiện tại.

60

GetCharWidthI

Truy xuất chiều rộng, theo tọa độ logic, của các chỉ số glyph liên tiếp trong một phạm vi xác định từ phông chữ hiện tại.

61

GetClipBox

Truy xuất kích thước của hình chữ nhật giới hạn chặt chẽ nhất xung quanh ranh giới cắt hiện tại.

62

GetColorAdjustment

Truy xuất các giá trị điều chỉnh màu cho ngữ cảnh thiết bị.

63

GetCurrentBitmap

Trả về một con trỏ đến hiện được chọn CBitmap vật.

64

GetCurrentBrush

Trả về một con trỏ đến hiện được chọn CBrush vật.

65

GetCurrentFont

Trả về một con trỏ đến hiện được chọn CFont vật.

66

GetCurrentPalette

Trả về một con trỏ đến hiện được chọn CPalette vật.

48

GetCurrentPen

Trả về một con trỏ đến hiện được chọn CPen vật.

67

GetCurrentPosition

Truy xuất vị trí hiện tại của bút (theo tọa độ logic).

68

GetDCBrushColor

Lấy màu bàn chải hiện tại.

69

GetDCPenColor

Lấy màu bút hiện tại.

70

GetDeviceCaps

Truy xuất một loại thông tin cụ thể về thiết bị cụ thể về khả năng của một thiết bị hiển thị nhất định.

71

GetFontData

Truy xuất thông tin chỉ số phông chữ từ tệp phông chữ có thể mở rộng. Thông tin cần truy xuất được xác định bằng cách chỉ định độ lệch vào tệp phông chữ và độ dài của thông tin cần trả về.

72

GetFontLanguageInfo

Trả về thông tin về phông chữ hiện được chọn cho ngữ cảnh hiển thị được chỉ định.

73

GetGlyphOutline

Truy xuất đường cong phác thảo hoặc bitmap cho một ký tự phác thảo trong phông chữ hiện tại.

74

GetGraphicsMode

Truy xuất chế độ đồ họa hiện tại cho ngữ cảnh thiết bị được chỉ định.

75

GetHalftoneBrush

Lấy một bàn chải bán sắc.

76

GetKerningPairs

Lấy các cặp kerning ký tự cho phông chữ hiện được chọn trong ngữ cảnh thiết bị được chỉ định.

77

GetLayout

Truy xuất bố cục của bối cảnh thiết bị (DC). Bố cục có thể từ trái sang phải (mặc định) hoặc từ phải sang trái (được nhân đôi).

78

GetMapMode

Truy xuất chế độ ánh xạ hiện tại.

79

GetMiterLimit

Trả về giới hạn bit cho ngữ cảnh thiết bị.

80

GetNearestColor

Lấy màu logic gần nhất với màu logic được chỉ định mà thiết bị đã cho có thể đại diện.

81

GetOutlineTextMetrics

Truy xuất thông tin chỉ số phông chữ cho phông chữ TrueType.

82

GetOutputCharWidth

Lấy độ rộng của các ký tự riêng lẻ trong một nhóm ký tự liên tiếp từ phông chữ hiện tại bằng cách sử dụng ngữ cảnh thiết bị đầu ra.

83

GetOutputTabbedTextExtent

Tính toán chiều rộng và chiều cao của một chuỗi ký tự trên bối cảnh thiết bị đầu ra.

84

GetOutputTextExtent

Tính toán chiều rộng và chiều cao của một dòng văn bản trên bối cảnh thiết bị đầu ra bằng cách sử dụng phông chữ hiện tại để xác định kích thước.

85

GetOutputTextMetrics

Truy xuất số liệu cho phông chữ hiện tại từ ngữ cảnh thiết bị đầu ra.

86

GetPath

Truy xuất các tọa độ xác định điểm cuối của các đường và điểm kiểm soát của các đường cong được tìm thấy trong đường dẫn được chọn vào ngữ cảnh thiết bị.

87

GetPixel

Lấy giá trị màu RGB của pixel tại điểm được chỉ định.

88

GetPolyFillMode

Truy xuất chế độ điền đa giác hiện tại.

89

GetROP2

Truy xuất chế độ vẽ hiện tại.

90

GetSafeHdc

Lợi nhuận m_hDC, bối cảnh thiết bị đầu ra.

91

GetStretchBltMode

Truy xuất chế độ kéo giãn bitmap hiện tại.

92

GetTabbedTextExtent

Tính chiều rộng và chiều cao của một chuỗi ký tự trên ngữ cảnh thiết bị thuộc tính.

93

GetTextAlign

Truy xuất các cờ căn chỉnh văn bản.

94

GetTextCharacterExtra

Truy xuất cài đặt hiện tại cho khoảng cách giữa các ký tự.

95

GetTextColor

Lấy màu văn bản hiện tại.

96

GetTextExtent

Tính toán chiều rộng và chiều cao của một dòng văn bản trên ngữ cảnh thiết bị thuộc tính bằng cách sử dụng phông chữ hiện tại để xác định kích thước.

97

GetTextExtentExPointI

Lấy số lượng ký tự trong một chuỗi được chỉ định sẽ vừa với một không gian được chỉ định và lấp đầy một mảng với phạm vi văn bản cho mỗi ký tự đó.

98

GetTextExtentPointI

Truy xuất chiều rộng và chiều cao của mảng chỉ số glyph được chỉ định.

99

GetTextFace

Sao chép tên kiểu chữ của phông chữ hiện tại vào bộ đệm dưới dạng chuỗi kết thúc bằng null.

100

GetTextMetrics

Truy xuất số liệu cho phông chữ hiện tại từ ngữ cảnh thiết bị thuộc tính.

101

GetViewportExt

Truy xuất phạm vi x- và y của khung nhìn.

102

GetViewportOrg

Truy xuất tọa độ x và y của điểm gốc khung nhìn.

103

GetWindow

Trả về cửa sổ được liên kết với ngữ cảnh thiết bị hiển thị.

104

GetWindowExt

Truy xuất phạm vi x- và y của cửa sổ được liên kết.

105

GetWindowOrg

Truy xuất tọa độ x và y của điểm gốc của cửa sổ được liên kết.

106

GetWorldTransform

Truy xuất chuyển đổi không gian thế giới hiện tại sang không gian trang.

107

GradientFill

Tô các cấu trúc hình chữ nhật và hình tam giác bằng màu chuyển sắc.

108

GrayString

Vẽ văn bản bị mờ (tô xám) tại vị trí nhất định.

109

HIMETRICtoDP

Chuyển đổi đơn vị HIMETRIC thành đơn vị thiết bị.

110

HIMETRICtoLP

Chuyển đổi đơn vị HIMETRIC thành đơn vị logic.

111

IntersectClipRect

Tạo vùng cắt mới bằng cách tạo giao điểm của vùng hiện tại và hình chữ nhật.

112

InvertRect

Đảo ngược nội dung của hình chữ nhật.

113

InvertRgn

Đảo ngược các màu trong một vùng.

114

IsPrinting

Xác định xem ngữ cảnh thiết bị có đang được sử dụng để in hay không.

115

LineTo

Vẽ một đường từ vị trí hiện tại lên đến, nhưng không bao gồm, một điểm.

116

LPtoDP

Chuyển đổi đơn vị logic thành đơn vị thiết bị.

117

LPtoHIMETRIC

Chuyển đổi đơn vị logic thành đơn vị HIMETRIC.

118

MaskBlt

Kết hợp dữ liệu màu cho bitmap nguồn và đích bằng cách sử dụng mặt nạ và hoạt động raster đã cho.

119

ModifyWorldTransform

Thay đổi chuyển đổi thế giới cho bối cảnh thiết bị bằng cách sử dụng chế độ được chỉ định.

120

MoveTo

Di chuyển vị trí hiện tại.

121

OffsetClipRgn

Di chuyển vùng cắt của thiết bị đã cho.

122

OffsetViewportOrg

Sửa đổi điểm gốc khung nhìn so với tọa độ của điểm gốc khung nhìn hiện tại.

123

OffsetWindowOrg

Sửa đổi điểm gốc cửa sổ so với tọa độ của điểm gốc cửa sổ hiện tại.

124

PaintRgn

Điền vào một vùng bằng bàn chải đã chọn.

125

PatBlt

Tạo ra một mẫu bit.

126

Pie

Vẽ một cái nêm hình chiếc bánh.

127

PlayMetaFile

Phát nội dung của siêu tệp được chỉ định trên thiết bị nhất định. Phiên bản nâng cao của PlayMetaFile hiển thị ảnh được lưu trữ trong siêu tệp định dạng nâng cao nhất định. Siêu tệp có thể được phát bất kỳ số lần nào.

128

PlgBlt

Thực hiện chuyển khối bit các bit dữ liệu màu từ hình chữ nhật được chỉ định trong ngữ cảnh thiết bị nguồn sang hình bình hành được chỉ định trong ngữ cảnh thiết bị nhất định.

129

PolyBezier

Vẽ một hoặc nhiều Bzier splines. Vị trí hiện tại không được sử dụng hoặc cập nhật.

130

PolyBezierTo

Vẽ một hoặc nhiều đường Bzier và di chuyển vị trí hiện tại đến điểm kết thúc của đường Bzier cuối cùng.

131

PolyDraw

Vẽ một tập hợp các đoạn thẳng và các đường Bzier. Chức năng này cập nhật vị trí hiện tại.

132

Polygon

Vẽ một đa giác bao gồm hai hoặc nhiều điểm (đỉnh) được nối với nhau bằng các đường.

133

Polyline

Vẽ một tập hợp các đoạn thẳng nối các điểm được chỉ định.

134

PolylineTo

Vẽ một hoặc nhiều đoạn thẳng và di chuyển vị trí hiện tại đến điểm kết thúc của đoạn thẳng cuối cùng.

135

PolyPolygon

Tạo hai hoặc nhiều đa giác được lấp đầy bằng cách sử dụng chế độ điền đa giác hiện tại. Các đa giác có thể rời rạc hoặc chúng có thể chồng lên nhau.

136

PolyPolyline

Vẽ nhiều chuỗi đoạn thẳng được kết nối. Chức năng này không sử dụng hoặc cập nhật vị trí hiện tại.

137

PtVisible

Chỉ định xem điểm đã cho có nằm trong vùng cắt hay không.

138

RealizePalette

Các mục nhập bảng màu trong bảng logic hiện tại vào bảng hệ thống.

139

Rectangle

Vẽ một hình chữ nhật bằng bút hiện tại và tô nó bằng bút vẽ hiện tại.

140

RectVisible

Xác định xem bất kỳ phần nào của hình chữ nhật đã cho nằm trong vùng cắt.

141

ReleaseAttribDC

Phát hành m_hAttribDC, ngữ cảnh thiết bị thuộc tính.

142

ReleaseOutputDC

Phát hành m_hDC, bối cảnh thiết bị đầu ra.

143

ResetDC

Cập nhật ngữ cảnh thiết bị m_hAttribDC.

144

RestoreDC

Khôi phục ngữ cảnh thiết bị về trạng thái trước đó được lưu với SaveDC.

145

RoundRect

Vẽ một hình chữ nhật với các góc tròn bằng bút hiện tại và tô bằng bút vẽ hiện tại.

146

SaveDC

Lưu trạng thái hiện tại của bối cảnh thiết bị.

147

ScaleViewportExt

Sửa đổi phạm vi chế độ xem liên quan đến các giá trị hiện tại.

148

ScaleWindowExt

Sửa đổi phạm vi cửa sổ liên quan đến các giá trị hiện tại.

149

ScrollDC

Cuộn một hình chữ nhật gồm các bit theo chiều ngang và chiều dọc.

150

SelectClipPath

Chọn đường dẫn hiện tại làm vùng cắt cho bối cảnh thiết bị, kết hợp vùng mới với bất kỳ vùng cắt hiện có nào bằng cách sử dụng chế độ được chỉ định.

151

SelectClipRgn

Kết hợp vùng đã cho với vùng cắt hiện tại bằng cách sử dụng chế độ được chỉ định.

152

SelectObject

Chọn đối tượng vẽ GDI chẳng hạn như bút.

153

SelectPalette

Chọn bảng hợp lý.

154

SelectStockObject

Chọn một trong các bút, bút vẽ hoặc phông chữ được xác định trước do Windows cung cấp.

155

SetAbortProc

Đặt chức năng gọi lại do lập trình viên cung cấp mà Windows sẽ gọi nếu lệnh in phải bị hủy bỏ.

156

SetArcDirection

Đặt hướng vẽ được sử dụng cho các chức năng cung tròn và hình chữ nhật.

157

SetAttribDC

Đặt m_hAttribDC, ngữ cảnh thiết bị thuộc tính.

158

SetBkColor

Đặt màu nền hiện tại.

159

SetBkMode

Đặt chế độ nền.

160

SetBoundsRect

Kiểm soát việc tích lũy thông tin hình chữ nhật giới hạn cho ngữ cảnh thiết bị được chỉ định.

161

SetBrushOrg

Chỉ định nguồn gốc cho bàn chải tiếp theo được chọn vào ngữ cảnh thiết bị.

162

SetColorAdjustment

Đặt các giá trị điều chỉnh màu cho ngữ cảnh thiết bị bằng các giá trị được chỉ định.

163

SetDCBrushColor

Đặt màu bàn chải hiện tại.

164

SetDCPenColor

Đặt màu bút hiện tại.

165

SetGraphicsMode

Đặt chế độ đồ họa hiện tại cho ngữ cảnh thiết bị được chỉ định.

166

SetLayout

Thay đổi bố cục của bối cảnh thiết bị (DC).

167

SetMapMode

Đặt chế độ ánh xạ hiện tại.

168

SetMapperFlags

Thay đổi thuật toán mà trình ánh xạ phông chữ sử dụng khi nó ánh xạ phông chữ logic sang phông chữ vật lý.

169

SetMiterLimit

Đặt giới hạn cho độ dài của các phép nối dấu ngoặc cho ngữ cảnh thiết bị.

170

SetOutputDC

Đặt m_hDC, ngữ cảnh thiết bị đầu ra.

171

SetPixel

Đặt pixel tại điểm được chỉ định thành màu gần đúng nhất của màu được chỉ định.

172

SetPixelV

Đặt pixel ở tọa độ được chỉ định thành màu gần đúng nhất của màu được chỉ định. SetPixelV nhanh hơn SetPixel bởi vì nó không cần trả về giá trị màu của điểm thực sự được sơn.

173

SetPolyFillMode

Đặt chế độ điền đa giác.

175

SetROP2

Đặt chế độ vẽ hiện tại.

176

SetStretchBltMode

Đặt chế độ kéo giãn bitmap.

177

SetTextAlign

Đặt cờ căn chỉnh văn bản.

178

SetTextCharacterExtra

Đặt khoảng cách giữa các ký tự.

179

SetTextColor

Đặt màu văn bản.

180

SetTextJustification

Thêm khoảng trắng vào các ký tự ngắt trong một chuỗi.

181

SetViewportExt

Đặt phạm vi x- và y của khung nhìn.

182

SetViewportOrg

Đặt điểm gốc của khung nhìn.

183

SetWindowExt

Đặt phạm vi x- và y của cửa sổ được liên kết.

184

SetWindowOrg

Đặt nguồn gốc cửa sổ của ngữ cảnh thiết bị.

185

SetWorldTransform

Đặt không gian thế giới hiện tại thành chuyển đổi không gian trang.

186

StartDoc

Thông báo cho trình điều khiển thiết bị rằng lệnh in mới đang bắt đầu.

187

StartPage

Thông báo cho trình điều khiển thiết bị rằng một trang mới đang bắt đầu.

188

StretchBlt

Di chuyển một bitmap từ một hình chữ nhật nguồn và thiết bị vào một hình chữ nhật đích, kéo dài hoặc nén bitmap nếu cần để vừa với kích thước của hình chữ nhật đích.

189

StrokeAndFillPath

Đóng bất kỳ hình nào đang mở trong một đường dẫn, vẽ đường viền của đường dẫn bằng cách sử dụng bút hiện tại và tô màu bên trong của nó bằng cách sử dụng bút vẽ hiện tại.

190

StrokePath

Hiển thị đường dẫn được chỉ định bằng cách sử dụng bút hiện tại.

191

TabbedTextOut

Viết một chuỗi ký tự tại một vị trí được chỉ định, mở rộng các tab đến các giá trị được chỉ định trong một mảng các vị trí dừng tab.

192

TextOut

Viết một chuỗi ký tự tại một vị trí được chỉ định bằng cách sử dụng phông chữ hiện được chọn.

193

TransparentBlt

Truyền một khối dữ liệu màu từ ngữ cảnh thiết bị nguồn được chỉ định sang ngữ cảnh thiết bị đích, hiển thị một màu cụ thể trong suốt trong quá trình truyền.

194

UpdateColors

Cập nhật vùng máy khách của bối cảnh thiết bị bằng cách khớp các màu hiện tại trong vùng máy khách với bảng màu hệ thống trên cơ sở từng pixel.

195

WidenPath

Xác định lại đường dẫn hiện tại là khu vực sẽ được vẽ nếu đường được vuốt bằng bút hiện được chọn vào ngữ cảnh thiết bị.

Dòng

Step 1 - Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một dự án tài liệu đơn dựa trên MFC mới với MFCGDIDemo Tên.

Step 2 - Sau khi dự án được tạo, hãy vào Trình khám phá Giải pháp và nhấp đúp vào MFCGDIDemoView.cpp trong thư mục Tệp Nguồn.

Step 3 - Vẽ đoạn thẳng như hình dưới đây trong CMFCGDIDemoView::OnDraw() phương pháp.

void CMFCGDIDemoView::OnDraw(CDC* pDC) {
   pDC->MoveTo(95, 125);
   pDC->LineTo(230, 125);
   CMFCGDIDemoDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;

   // TODO: add draw code for native data here
}

Step 4- Chạy ứng dụng này. Bạn sẽ thấy kết quả sau.

Step 5 - Phương thức CDC :: MoveTo () được sử dụng để thiết lập vị trí bắt đầu của một dòng.

Khi sử dụng LineTo (), chương trình bắt đầu từ điểm MoveTo () đến điểm kết thúc LineTo ().

Sau LineTo () khi bạn không gọi MoveTo (), và gọi lại LineTo () với giá trị điểm khác, chương trình sẽ vẽ một đường thẳng từ LineTo () trước đó đến điểm LineTo () mới.

Step 6 - Để vẽ các đường khác nhau, bạn có thể sử dụng thuộc tính này như thể hiện trong đoạn mã sau.

void CMFCGDIDemoView::OnDraw(CDC* pDC) { 
   pDC->MoveTo(95, 125);
   pDC->LineTo(230, 125);
   pDC->LineTo(230, 225);
   pDC->LineTo(95, 325);
   CMFCGDIDemoDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;

   // TODO: add draw code for native data here 
}

Step 7- Chạy ứng dụng này. Bạn sẽ thấy kết quả sau.

Polylines

A polylinelà một loạt các đường kết nối. Các dòng được lưu trữ trong một mảng các giá trị POINT hoặc CPoint. Để vẽ một polyline, bạn sử dụng phương thức CDC :: Polyline (). Để vẽ một đường đa giác, cần có ít nhất hai điểm. Nếu bạn xác định nhiều hơn hai điểm, mỗi dòng sau điểm đầu tiên sẽ được vẽ từ điểm trước đến điểm tiếp theo cho đến khi tất cả các điểm đã được bao gồm.

Step 1 - Chúng ta hãy xem xét một ví dụ đơn giản.

void CMFCGDIDemoView::OnDraw(CDC* pDC) {
   CPoint Pt[7];
   Pt[0] = CPoint(20, 150);
   Pt[1] = CPoint(180, 150);
   Pt[2] = CPoint(180, 20);
   pDC−Polyline(Pt, 3);
   
   CMFCGDIDemoDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;

   // TODO: add draw code for native data here
}

Step 2 - Khi bạn chạy ứng dụng này, bạn sẽ thấy kết quả sau.

Hình chữ nhật

A rectanglelà một hình hình học có bốn cạnh tạo thành bốn góc vuông. Giống như đường thẳng, để vẽ một hình chữ nhật, bạn phải xác định nơi bắt đầu và nơi kết thúc. Để vẽ một hình chữ nhật, bạn có thể sử dụng phương thức CDC :: Rectangle ().

Step 1 - Chúng ta hãy xem xét một ví dụ đơn giản.

void CMFCGDIDemoView::OnDraw(CDC* pDC) {
   pDC->Rectangle(15, 15, 250, 160);
   
   CMFCGDIDemoDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;

   // TODO: add draw code for native data here
}

Step 2 - Khi bạn chạy ứng dụng này, bạn sẽ thấy kết quả sau.

Hình vuông

A square là một hình hình học có bốn cạnh tạo thành bốn góc vuông nhưng mỗi cạnh phải có độ dài bằng nhau.

Chúng ta hãy xem xét một ví dụ đơn giản.

void CMFCGDIDemoView::OnDraw(CDC* pDC) {
   pDC->Rectangle(15, 15, 250, 250);
   
   CMFCGDIDemoDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;

   // TODO: add draw code for native data here
}

Khi bạn chạy ứng dụng này, bạn sẽ thấy kết quả sau.

Bánh nướng

A pielà một phần của hình elip được giới hạn bởi hai đường kéo dài từ tâm của hình elip đến một cạnh của mỗi đường. Để vẽ một chiếc bánh, bạn có thể sử dụng phương thức CDC :: Pie () như hình dưới đây:

BOOL Pie (int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);

  • Điểm (x1, y1) xác định góc trên bên trái của hình chữ nhật, trong đó hình elip đại diện cho hình bánh phù hợp. Điểm (x2, y2) là góc dưới cùng bên phải của hình chữ nhật.

  • Điểm (x3, y3) chỉ định góc bắt đầu của hình bánh theo hướng ngược chiều kim đồng hồ mặc định.

  • Điểm (x4, y4) là điểm cuối của hình bánh.

Chúng ta hãy xem xét một ví dụ đơn giản.

void CMFCGDIDemoView::OnDraw(CDC* pDC) {
   pDC->Pie(40, 20, 226, 144, 155, 32, 202, 115);
   
   CMFCGDIDemoDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;

   // TODO: add draw code for native data here
}

Step 2 - Khi bạn chạy ứng dụng này, bạn sẽ thấy kết quả sau.

Vòng cung

Cung là một phần hoặc đoạn của hình elip, có nghĩa là cung là một hình elip không hoàn chỉnh. Để vẽ một cung tròn, bạn có thể sử dụng phương thức CDC :: Arc ().

BOOL Arc (int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);

Lớp CDC được trang bị phương thức SetArcDirection ().

Đây là cú pháp -

int SetArcDirection(int nArcDirection)

Sr.No. Giá trị & Định hướng
1

AD_CLOCKWISE

Hình vẽ theo chiều kim đồng hồ

2

AD_COUNTERCLOCKWISE

Hình vẽ ngược chiều kim đồng hồ

Step 1 - Chúng ta hãy xem xét một ví dụ đơn giản.

void CMFCGDIDemoView::OnDraw(CDC* pDC) {
   pDC->SetArcDirection(AD_COUNTERCLOCKWISE);
   pDC->Arc(20, 20, 226, 144, 202, 115, 105, 32);
   
   CMFCGDIDemoDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;

   // TODO: add draw code for native data here
}

Step 2 - Khi bạn chạy ứng dụng này, bạn sẽ thấy kết quả sau.

Hợp âm

Các cung tròn mà chúng ta đã vẽ cho đến nay được coi là các hình mở vì chúng được tạo bởi một đường thẳng có điểm đầu và điểm cuối (không giống như hình tròn hoặc hình chữ nhật thì không). Achord là một cung tròn mà hai đầu của nó được nối với nhau bằng một đoạn thẳng.

Để vẽ một hợp âm, bạn có thể sử dụng phương thức CDC :: Chord ().

BOOL Chord (int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4);

Chúng ta hãy xem xét một ví dụ đơn giản.

void CMFCGDIDemoView::OnDraw(CDC* pDC) {
   pDC->SetArcDirection(AD_CLOCKWISE);
   pDC->Chord(20, 20, 226, 144, 202, 115, 105, 32);
   
   CMFCGDIDemoDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;

   // TODO: add draw code for native data here
}

Khi bạn chạy ứng dụng trên, bạn sẽ thấy kết quả sau.

Hướng vòng cung trong ví dụ này được đặt theo chiều kim đồng hồ.

Màu sắc

Các colorlà một trong những đồ vật cơ bản nhất làm tăng vẻ thẩm mỹ của một đồ vật. Màu sắc là một đối tượng phi không gian được thêm vào một đối tượng để sửa đổi một số khía cạnh trực quan của nó. Thư viện MFC, kết hợp với Win32 API, cung cấp các hành động khác nhau mà bạn có thể sử dụng để tận dụng các khía cạnh khác nhau của màu sắc.

Macro RGB hoạt động giống như một hàm và cho phép bạn chuyển ba giá trị số được phân tách bằng dấu phẩy. Mỗi giá trị phải nằm trong khoảng từ 0 đến 255 như trong đoạn mã sau.

void CMFCGDIDemoView::OnDraw(CDC* pDC) {
   COLORREF color = RGB(239, 15, 225);
}

Chúng ta hãy xem xét một ví dụ đơn giản.

void CMFCGDIDemoView::OnDraw(CDC* pDC) {
   COLORREF color = RGB(239, 15, 225);
   pDC->SetTextColor(color);
   pDC->TextOut(100, 80, L"MFC GDI Tutorial", 16);
   
   CMFCGDIDemoDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;

   // TODO: add draw code for native data here
}

Khi bạn chạy ứng dụng này, bạn sẽ thấy kết quả sau.

Phông chữ

CFontđóng gói phông chữ giao diện thiết bị đồ họa Windows (GDI) và cung cấp các chức năng thành viên để thao tác với phông chữ. Để sử dụng một đối tượng CFont, hãy xây dựng một đối tượng CFont và đính kèm một phông chữ Windows vào nó, sau đó sử dụng các hàm thành viên của đối tượng để thao tác với phông chữ.

Sr.No. Tên & Mô tả
1

CreateFont

Khởi tạo CFont với các đặc tính được chỉ định.

2

CreateFontIndirect

Khởi tạo đối tượng CFont với các đặc điểm được đưa ra trong LOGFONT kết cấu.

3

CreatePointFont

Khởi tạo CFont với chiều cao được chỉ định, được đo bằng phần mười của một điểm và kiểu chữ.

4

CreatePointFontIndirect

Giống như CreateFontIndirect ngoại trừ việc chiều cao phông chữ được đo bằng phần mười của một điểm chứ không phải đơn vị logic.

5

FromHandle

Trả về một con trỏ đến đối tượng CFont khi được cung cấp Windows HFONT.

6

GetLogFont

Điền vào LOGFONT với thông tin về phông chữ logic được đính kèm với đối tượng CFont.

Chúng ta hãy xem xét một ví dụ đơn giản.

void CMFCGDIDemoView::OnDraw(CDC* pDC) {
   CFont font;
   font.CreatePointFont(920, L"Garamond");
   CFont *pFont = pDC->SelectObject(&font);
   COLORREF color = RGB(239, 15, 225);
   pDC->SetTextColor(color);
   pDC->TextOut(100, 80, L"MFC GDI Tutorial", 16);
   pDC->SelectObject(pFont);
   font.DeleteObject();
   
   CMFCGDIDemoDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
   return;

   // TODO: add draw code for native data here
}

Khi bạn chạy ứng dụng trên, bạn sẽ thấy kết quả sau.

Bút mực

A penlà một công cụ được sử dụng để vẽ các đường thẳng và đường cong trên bối cảnh thiết bị. Trong lập trình đồ họa, bút cũng được sử dụng để vẽ đường viền của một hình dạng khép kín hình học như hình chữ nhật hoặc hình đa giác. Microsoft Windows xem xét hai loại bút -cosmeticgeometric.

Một chiếc bút được coi là mỹ phẩm khi nó chỉ có thể được sử dụng để vẽ những đường đơn giản có chiều rộng cố định, nhỏ hơn hoặc bằng 1 pixel. Một cây bút là hình học khi nó có thể có các chiều rộng khác nhau và các đầu khác nhau. MFC cung cấp một lớpCPen bao gồm bút giao diện thiết bị đồ họa Windows (GDI).

Sr.No. Tên & Mô tả
1

CreatePen

Tạo một cây bút thẩm mỹ hoặc hình học hợp lý với các thuộc tính kiểu dáng, chiều rộng và nét vẽ được chỉ định và gắn nó vào đối tượng CPen.

2

CreatePenIndirect

Tạo một cây bút với kiểu dáng, chiều rộng và màu sắc được cung cấp trong cấu trúc LOGPEN và gắn nó vào đối tượng CPen.

3

FromHandle

Trả về một con trỏ đến đối tượng CPen khi được cung cấp Windows HPEN.

4

GetExtLogPen

Nhận cấu trúc cơ bản EXTLOGPEN.

5

GetLogPen

Nhận cấu trúc cơ bản LOGPEN .

Sr.No. Name & Description
1

PS_SOLID

Một đường liền nét.

2

PS_DASH

Một đường liên tục với các ngắt nét đứt quãng.

3

PS_DOT

Một dòng có dấu chấm bị gián đoạn ở mọi pixel khác.

4

PS_DASHDOT

Một sự kết hợp của các điểm gạch ngang và chấm xen kẽ.

5

PS_DASHDOTDOT

Sự kết hợp giữa dấu gạch ngang và dấu chấm đôi.

6

PS_NULL

Không có dòng hiển thị.

7

PS_INSIDEFRAME

Một đường được vẽ ngay bên trong đường viền của một hình dạng khép kín.

Chúng ta hãy xem xét một ví dụ đơn giản.

void CMFCGDIDemoView::OnDraw(CDC* pDC) {
   CPen pen;
   pen.CreatePen(PS_DASHDOTDOT, 1, RGB(160, 75, 90));
   pDC->SelectObject(&pen);
   pDC->Rectangle(25, 35, 250, 125);
   
   CMFCGDIDemoDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;

   // TODO: add draw code for native data here
}

Khi bạn chạy ứng dụng trên, bạn sẽ thấy kết quả sau.

Bút vẽ

A brushlà một công cụ vẽ được sử dụng để điền vào các hình dạng khép kín hoặc phần bên trong của các đường. Một chiếc bàn chải hoạt động giống như nhặt một thùng sơn và đổ nó vào đâu đó. MFC cung cấp một lớpCBrush bao gồm một bàn chải giao diện thiết bị đồ họa Windows (GDI).

Sr.NO. Tên & Mô tả
1

CreateBrushIndirect

Khởi tạo một bàn chải với kiểu, màu và mẫu được chỉ định trong cấu trúc LOGBRUSH.

2

CreateDIBPatternBrush

Khởi tạo một bàn chải với một mẫu được chỉ định bởi một bitmap độc lập với thiết bị (DIB).

3

CreateHatchBrush

Khởi tạo một bàn chải với kiểu tô và màu được chỉ định.

4

CreatePatternBrush

Khởi tạo một bàn chải với một mẫu được chỉ định bởi một bitmap.

5

CreateSolidBrush

Khởi tạo một bàn chải với màu đặc được chỉ định.

6

CreateSysColorBrush

Tạo một bàn chải là màu hệ thống mặc định.

7

FromHandle

Trả về một con trỏ đến một đối tượng CBrush khi được cung cấp một tay cầm cho một đối tượng Windows HBRUSH.

số 8

GetLogBrush

Nhận cấu trúc LOGBRUSH.

Chúng ta hãy xem xét một ví dụ đơn giản.

void CMFCGDIDemoView::OnDraw(CDC* pDC) {
   CBrush brush(RGB(100, 150, 200));
   CBrush *pBrush = pDC->SelectObject(&brush);
   pDC->Rectangle(25, 35, 250, 125);
   pDC->SelectObject(pBrush);
   
   CMFCGDIDemoDoc* pDoc = GetDocument();
   ASSERT_VALID(pDoc);
   if (!pDoc)
      return;

   // TODO: add draw code for native data here
}

Khi bạn chạy ứng dụng này, bạn sẽ thấy kết quả sau.

A librarylà một nhóm các chức năng, lớp hoặc các tài nguyên khác có thể được cung cấp cho các chương trình cần các thực thể đã được triển khai mà không cần biết các chức năng, lớp hoặc tài nguyên này được tạo ra như thế nào hoặc cách chúng hoạt động. Thư viện giúp lập trình viên dễ dàng sử dụng các hàm, lớp và tài nguyên, v.v. do một người hoặc công ty khác tạo ra và tin tưởng rằng nguồn bên ngoài này đáng tin cậy và hiệu quả. Một số tính năng độc đáo liên quan đến thư viện là:

  • Thư viện được tạo ra và hoạt động giống như một chương trình thông thường bình thường, sử dụng các hàm hoặc các tài nguyên khác và giao tiếp với các chương trình khác.

  • Để thực hiện chức năng của nó, một thư viện chứa các chức năng mà các chương trình khác cần để hoàn thành chức năng của chúng.

  • Đồng thời, thư viện có thể sử dụng một số chức năng mà các chương trình khác không cần.

  • Chương trình sử dụng thư viện, còn được gọi là các máy khách của thư viện.

Có hai loại hàm bạn sẽ tạo hoặc đưa vào thư viện của mình -

  • Một chức năng nội bộ là một chức năng chỉ được sử dụng bởi chính thư viện và khách hàng của thư viện sẽ không cần quyền truy cập vào các chức năng này.

  • Các chức năng bên ngoài là những chức năng có thể được truy cập bởi các máy khách của thư viện.

Có hai loại thư viện lớn mà bạn sẽ xử lý trong các chương trình của mình -

  • Thư viện tĩnh
  • Thư viện động

Thư viện tĩnh

A static librarylà một tệp chứa các hàm, lớp hoặc tài nguyên mà chương trình bên ngoài có thể sử dụng để bổ sung cho chức năng của nó. Để sử dụng một thư viện, người lập trình phải tạo một liên kết đến nó. Dự án có thể là ứng dụng console, Win32 hoặc ứng dụng MFC. Tệp thư viện có phần mở rộng là lib.

Step 1 - Chúng ta hãy xem xét một ví dụ đơn giản về thư viện tĩnh bằng cách tạo một Dự án Win32 mới.

Step 2 - Trên hộp thoại Application Wizard, chọn tùy chọn Static Library.

Step 3 - Nhấn Hoàn tất để tiếp tục.

Step 4 - Nhấp chuột phải vào dự án trong trình khám phá giải pháp và thêm tệp tiêu đề từ tùy chọn menu Thêm → Mục mới….

Step 5 - Nhập Calculator.h vào trường Tên và nhấp vào Thêm.

Thêm mã sau vào tệp tiêu đề -

#pragma once
#ifndef _CALCULATOR_H_
#define _CALCULATOR_H_
double Min(const double *Numbers, const int Count);
double Max(const double *Numbers, const int Count);
double Sum(const double *Numbers, const int Count);
double Average(const double *Numbers, const int Count);
long GreatestCommonDivisor(long Nbr1, long Nbr2);
#endif // _CALCULATOR_H_

Step 6 - Thêm tệp nguồn (* .cpp) trong dự án.

Step 7 - Nhập Calculator.cpp vào trường Tên và nhấp vào Thêm.

Step 8 - Thêm mã sau vào tệp * .cpp -

#include "StdAfx.h"
#include "Calculator.h"
double Min(const double *Nbr, const int Total) {
   double Minimum = Nbr[0];
   for (int i = 0; i < Total; i++)
      if (Minimum > Nbr[i])
         Minimum = Nbr[i];
   return Minimum;
}
double Max(const double *Nbr, const int Total) {
   double Maximum = Nbr[0];
   for (int i = 0; i < Total; i++)
      if (Maximum < Nbr[i])
         Maximum = Nbr[i];
   return Maximum;
}
double Sum(const double *Nbr, const int Total) {
   double S = 0;
   for (int i = 0; i < Total; i++)
      S += Nbr[i];
   return S;
}
double Average(const double *Nbr, const int Total) {
   double avg, S = 0;
   for (int i = 0; i < Total; i++)
       S += Nbr[i];
   avg = S / Total;
   return avg;
}
long GreatestCommonDivisor(long Nbr1, long Nbr2) {
   while (true) {
      Nbr1 = Nbr1 % Nbr2;
      if (Nbr1 == 0)
         return Nbr2;
      Nbr2 = Nbr2 % Nbr1;
      if (Nbr2 == 0)
         return Nbr1;
   }
}

Step 9 - Xây dựng thư viện này từ menu chính, bằng cách nhấp vào Build → Build MFCLib.

Step 10 - Khi xây dựng thành công thư viện sẽ hiển thị thông báo trên.

Step 11 - Để sử dụng các chức năng này từ thư viện, chúng ta hãy thêm một ứng dụng hộp thoại MFC khác dựa trên File → New → Project.

Step 12 - Đi đến thư mục MFCLib \ Debug và sao chép tệp tiêu đề và tệp * .lib vào dự án MFCLibTest như được hiển thị trong ảnh chụp nhanh sau.

Step 13 - Để thêm thư viện vào dự án hiện tại, trên menu chính, nhấp vào Dự án → Thêm Mục hiện có và chọn MFCLib.lib.

Step 14 - Thiết kế hộp thoại của bạn như trong ảnh chụp sau.

Step 15 - Thêm biến giá trị cho cả hai điều khiển chỉnh sửa kiểu giá trị kép.

Step 16 - Thêm biến giá trị cho điều khiển Văn bản tĩnh, ở cuối hộp thoại.

Step 17 - Thêm trình xử lý sự kiện cho nút Tính toán.

Để thêm chức năng từ thư viện, chúng tôi cần đưa tệp tiêu đề vào tệp CMFCLibTestDlg.cpp.

#include "stdafx.h"
#include "MFCLibTest.h"
#include "MFCLibTestDlg.h"
#include "afxdialogex.h"
#include "Calculator.h"

Step 18 - Đây là phần thực hiện của button event handler.

void CMFCLibTestDlg::OnBnClickedButtonCal() {
   // TODO: Add your control notification handler code here
   UpdateData(TRUE);
   CString strTemp;
   double numbers[2];
   numbers[0] = m_Num1;
   numbers[1] = m_Num2;

   strTemp.Format(L"%.2f", Max(numbers,2));
   m_strText.Append(L"Max is:\t" + strTemp);

   strTemp.Format(L"%.2f", Min(numbers, 2));
   m_strText.Append(L"\nMin is:\t" + strTemp);
   
   strTemp.Format(L"%.2f", Sum(numbers, 2));
   m_strText.Append(L"\nSum is:\t" + strTemp);

   strTemp.Format(L"%.2f", Average(numbers, 2));
   m_strText.Append(L"\nAverage is:\t" + strTemp);

   strTemp.Format(L"%d", GreatestCommonDivisor(m_Num1, m_Num2));
   m_strText.Append(L"\nGDC is:\t" + strTemp);

   UpdateData(FALSE);
}

Step 19 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 20- Nhập hai giá trị vào trường chỉnh sửa và nhấp vào Tính toán. Bây giờ bạn sẽ thấy kết quả sau khi tính toán từ thư viện.

Thư viện động

Win32 DLL là một thư viện có thể được cung cấp cho các chương trình chạy trên máy tính Microsoft Windows. Là một thư viện bình thường, nó được tạo thành từ các hàm và / hoặc các tài nguyên khác được nhóm trong một tệp.

Chữ viết tắt DLL là viết tắt của Thư viện liên kết động. Điều này có nghĩa là, trái ngược với thư viện tĩnh, một DLL cho phép lập trình viên quyết định khi nào và cách thức các ứng dụng khác sẽ được liên kết với loại thư viện này.

Ví dụ, một DLL cho phép các ứng dụng khác nhau sử dụng thư viện của nó khi chúng thấy phù hợp và cần thiết. Trên thực tế, các ứng dụng được tạo trên các môi trường lập trình khác nhau có thể sử dụng các chức năng hoặc tài nguyên được lưu trữ trong một DLL cụ thể. Vì lý do này, một ứng dụng liên kết động với thư viện.

Step 1 - Chúng ta hãy xem xét một ví dụ đơn giản bằng cách tạo một Dự án Win32 mới.

Step 2 - Trong phần Loại ứng dụng, nhấp vào nút radio DLL.

Step 3 - Nhấn Hoàn tất để tiếp tục.

Step 4 - Thêm các chức năng sau vào tệp MFCDynamicLib.cpp và hiển thị các định nghĩa của nó bằng cách sử dụng -

extern "C" _declspec(dllexport)

Step 5 - Sử dụng công cụ sửa đổi _declspec (dllexport) cho từng chức năng sẽ được truy cập bên ngoài DLL.

// MFCDynamicLib.cpp : Defines the exported functions for the DLL application.//

#include "stdafx.h"

extern "C" _declspec(dllexport) double Min(const double *Numbers, const int Count);
extern "C" _declspec(dllexport) double Max(const double *Numbers, const int Count);
extern "C" _declspec(dllexport) double Sum(const double *Numbers, const int Count);
extern "C" _declspec(dllexport) double Average(const double *Numbers, const int Count);
extern "C" _declspec(dllexport) long GreatestCommonDivisor(long Nbr1, long Nbr2);

double Min(const double *Nbr, const int Total) {
   double Minimum = Nbr[0];
   for (int i = 0; i < Total; i++)
      if (Minimum > Nbr[i])
         Minimum = Nbr[i];
   return Minimum;
}
double Max(const double *Nbr, const int Total) {
   double Maximum = Nbr[0];
   for (int i = 0; i < Total; i++)
      if (Maximum < Nbr[i])
         Maximum = Nbr[i];
   return Maximum;
}
double Sum(const double *Nbr, const int Total) {
   double S = 0;
   for (int i = 0; i < Total; i++)
      S += Nbr[i];
   return S;
}
double Average(const double *Nbr, const int Total){
   double avg, S = 0;
   for (int i = 0; i < Total; i++)
      S += Nbr[i];
   avg = S / Total;
   return avg;
}
long GreatestCommonDivisor(long Nbr1, long Nbr2) {
   while (true) {
      Nbr1 = Nbr1 % Nbr2;
      if (Nbr1 == 0)
         return Nbr2;
      Nbr2 = Nbr2 % Nbr1;
      if (Nbr2 == 0)
         return Nbr1;
   }
}

Step 6 - Để tạo DLL, trên menu chính, nhấp vào Build > Build MFCDynamicLib từ menu chính.

Step 7 - Khi DLL được tạo thành công, bạn sẽ thấy thông tin hiển thị trong cửa sổ đầu ra.

Step 8 - Mở Windows Explorer và sau đó là thư mục Gỡ lỗi của dự án hiện tại.

Step 9 - Chú ý rằng một tệp có phần mở rộng dll và một tệp khác có phần mở rộng lib đã được tạo.

Step 10 - Để kiểm tra tệp này với phần mở rộng dll, chúng ta cần tạo một ứng dụng dựa trên hộp thoại MFC mới từ Tệp → Mới → Dự án.

Step 11 - Vào thư mục MFCDynamicLib \ Debug và sao chép các tệp * .dll và * .lib vào dự án MFCLibTest như trong ảnh chụp sau.

Step 12 - Để thêm DLL vào dự án hiện tại, trên menu chính, nhấp vào Dự án → Thêm Mục hiện có, sau đó, chọn tệp MFCDynamicLib.lib.

Step 13 - Thiết kế hộp thoại của bạn như trong ảnh chụp sau.

Step 14 - Thêm biến giá trị cho cả hai điều khiển chỉnh sửa kiểu giá trị kép.

Step 15 - Thêm biến giá trị cho điều khiển Văn bản tĩnh, ở cuối hộp thoại.

Step 16 - Thêm trình xử lý sự kiện cho nút Tính toán.

Step 17 - Trong dự án đang sử dụng DLL, mỗi chức năng sẽ được truy cập phải được khai báo bằng sửa đổi _declspec (dllimport).

Step 18 - Thêm khai báo hàm sau trong tệp MFCLibTestDlg.cpp.

extern "C" _declspec(dllimport) double Min(const double *Numbers, const int Count);
extern "C" _declspec(dllimport) double Max(const double *Numbers, const int Count);
extern "C" _declspec(dllimport) double Sum(const double *Numbers, const int Count);
extern "C" _declspec(dllimport) double Average(const double *Numbers, const int Count);
extern "C" _declspec(dllimport) long GreatestCommonDivisor(long Nbr1, long Nbr2);

Step 19 - Đây là phần thực hiện của button event handler.

void CMFCLibTestDlg::OnBnClickedButtonCal() {

   // TODO: Add your control notification handler code here
   UpdateData(TRUE);

   CString strTemp;
   double numbers[2];
   numbers[0] = m_Num1;
   numbers[1] = m_Num2;

   strTemp.Format(L"%.2f", Max(numbers,2));
   m_strText.Append(L"Max is:\t" + strTemp);

   strTemp.Format(L"%.2f", Min(numbers, 2));
   m_strText.Append(L"\nMin is:\t" + strTemp);

   strTemp.Format(L"%.2f", Sum(numbers, 2));
   m_strText.Append(L"\nSum is:\t" + strTemp);

   strTemp.Format(L"%.2f", Average(numbers, 2));
   m_strText.Append(L"\nAverage is:\t" + strTemp);

   strTemp.Format(L"%d", GreatestCommonDivisor(m_Num1, m_Num2));
   m_strText.Append(L"\nGDC is:\t" + strTemp);
 
   UpdateData(FALSE);
}

Step 20 - Khi đoạn mã trên được biên dịch và thực thi, bạn sẽ thấy kết quả như sau.

Step 21- Nhập hai giá trị vào trường chỉnh sửa và nhấp vào Tính toán. Bây giờ bạn sẽ thấy kết quả sau khi tính toán từ DLL.