SỬ DỤNG FRAMEWINDOW LAØM GIAO DIỆN CHÍNH:

Một phần của tài liệu Lập trình Windows với MFC Microsoft Visual C++ 6.0 pdf (Trang 71 - 77)

KHUNG CỬA SỔ GIAO DIỆN CHÍNH

10.5SỬ DỤNG FRAMEWINDOW LAØM GIAO DIỆN CHÍNH:

Kế thừa từ CWnd, CFrameWnd và các lớp kế thừa từ nó có thể dùng khai báo các đối tượng cửa sổ giao diện chính của ứng dụng.

10.5.1 Thực hiện ứng dụng với giao diện chính là CFrameWnd:

2 Thực hành 1: Thực hiện ứng dụng với cửa sổ chính là frame window. ƒ Tạo dự án VD28 chỉ chứa lớp CEmpApp kế thừa từ CWinApp.

ƒ Trong hành vi InitInstance của CEmpApp, khai báo biến con trỏ đối tượng CFrameWnd* và dùng nó làm cửa sổ giao diện chính:

BOOL CEmpApp::InitInstance( ) {

CFrameWnd *main = new CFrameWnd;

m_pMainWnd = main; // frame window as the main window main->Create (

AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW, LoadCursor(IDC_MAINFRAME), NULL, LoadIcon(IDR_MAINFRAME) ),

"Emp.Example 28" );

main->ShowWindow(SW_SHOW); // Show the frame window return TRUE;

}

124Lập trình Windows với MFC - Microsoft Visual C++ 6.0 - Lê Ngọc Thạnh - lntmail@yahoo.com

2 Thực hành 2: Thực hiện ứng dụng tương tự VD28, cài hệ thống menu tương tự ví dụ chương 7 cho đối tượng frame window.

ƒ Tạo mới dự án VD29 tương tự dự án VD28.

ƒ Tạo mới menu resource với số hiệu IDR_MAINFRAME, thiết kế menu này như mô tả ở chương 7.

ƒ Tạo mới bảng phím tắt với số hiệu IDR_MAINFRAME. Khai báo nội dung bảng phím tắt như mục (7.5).

ƒ Hành vi InitInstance của CEmpApp thực hiện khai báo con trỏ đối tượng CFrameWnd*. Dùng hành vi LoadFrame của đối tượng này để khởi động thông số cho nó từ các resource liên quan:

BOOL CEmpApp::InitInstance() {

CFrameWnd *main = new CFrameWnd; m_pMainWnd = main;

main->LoadFrame(IDR_MAINFRAME);

main->ShowWindow(SW_SHOW); // Show the frame window return TRUE;

}

10.5.2 String Table và CFrameWnd:

StringTable, một thành phần trong resource của ứng dụng, dùng chứa các giá trị hằng chuỗi. Mỗi hằng chuỗi có một số hiệu phân biệt. Việc tạo mới hằng chuỗi trong resource cửa ứng dụng được thực hiện như sau:

ƒ Tạo mới resource (như 2.8). Lưu ý chọn resource type là String Table.

Khung cửa sổ giao diện chính 125

- ID = Số hiệu hằng chuỗi.

- Caption = Nội dung hằng chuỗi. Gõ phím Enter để kết thúc. ƒ Cuối cùng, lưu và đóng màn hình khai báo StringTable.

Φ Sử dụng hằng chuỗi trong StringTable: Có thể sử dụng hằng chuỗi trong StringTable làm giá trị cho biến chuỗi trong chương trình. Đối với biến chuỗi được quản lý bởi đối tượng chuỗi CString, xử lý này được thực hiện thông qua hành vi sau:

BOOL CString::LoadString (

UINT nID // Số hiệu hằng chuỗi trong resource ); (adsbygoogle = window.adsbygoogle || []).push({});

Sau đây là một ví dụ khởi tạo giá trị chuỗi myString từ string resource: CString myString;

myString.LoadString (ID_GAME_OPTION );

Φ Dùng hằng chuỗi trong Stringtable làm tiêu đề frame window:

Hằng chuỗi có số hiệu trùng với giá trị số hiệu làm tham số nIDResource cho hành vi khởi tạo thông số LoadFrame của đối tượng frame window sẽ được sử dụng làm tiêu đề của frame window này.

ƒ Mở dự án VD29.

ƒ Tạo mới hằng chuỗi “Emp.Example 29” trong StringTable với số hiệu là IDR_MAINFRAME.

ƒ Thực hiện chạy thử ứng dụng và quan sát tiêu đề cửa frame window. 2 Thực hành 3: Thực hiện ứng dụng như VD29; thanh statusbar với ba mục

(pane): mục thứ nhất chứa nội dung "Mr.Emp", mục thứ hai chứa nội dung "Hello world!", mục thứ ba hiển thị thông tin hoạt động của ứng dụng. HD: CFrameWnd không có sẵn statusbar. Dùng CEmpFrame kế thừa CFrameWnd và bổ sung đối tượng thuộc tính này. Hành vi OnCreate của CEmpFrame thực hiện khởi tạo thông số cho đối tượng statusbar. Dùng CEmpFrame khai báo đối tượng cửa số chính của ứng dụng.

ƒ Tạo dự án VD30 như VD29.

ƒ Bổ sung lớp CEmpFrame kế thừa CFrameWnd. Xem (5.4.1).

ƒ Bổ sung đối tượng thuộc tính protected m_status thuộc lớp CStatusBar cho lớp CEmpFrame:

CStatusBar m_status;

ƒ Bổ sung hành vi OnCreate (xử lý WM_CREATE) cho CEmpFrame và thực hiện cài đặt như sau:

126Lập trình Windows với MFC - Microsoft Visual C++ 6.0 - Lê Ngọc Thạnh - lntmail@yahoo.com

int CEmpFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {

if (CFrameWnd::OnCreate( lpCreateStruct ) == -1) return -1;

// The IDs of all statusbar’panes

UINT ID_array[3] = { 1, 1, ID_SEPARATOR };

m_status.Create( this ); // Thanh statusbar chính m_status.SetIndicators( ID_array, 3 );

m_status.SetPaneText( 0, "Mr.Emp" ); m_status.SetPaneText( 1, "Hello world!" ); // Set the size of each pane on statusbar

m_status.SetPaneInfo( 0, 1000, 0, 40 ); m_status.SetPaneInfo( 1, 1001, 0, 70 );

m_status.SetPaneInfo( 2, ID_SEPARATOR, 0, 300 ); return 0;

}

2 Thực hành 4: Viết ứng dụng như VD30 với thanh công cụ có 4 nút chọn tương ứng 4 mục chọn trong hệ thống menu.

ƒ Tạo dự án VD31 như VD30.

ƒ Tạo mới toolbar resource có số hiệu IDR_MAINFRAME với các nút chọn tương ứng các mục menu.

ƒ Bổ sung đối tượng thuộc tính m_toolbar thuộc lớp CToolBar cho lớp CEmpFrame. Hành vi OnCreate của CEmpFrame thực hiện khởi tạo thông số cho các đối tượng m_status và m_toolbar, sau đó kết đối tượng m_toolbar vào frame window

int CEmpFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {

... // Các cài đặt như VD30 m_toolbar.CreateEx ( this,

TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY ); | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY ); m_toolbar.LoadToolBar ( IDR_MAINFRAME ); (adsbygoogle = window.adsbygoogle || []).push({});

m_toolbar.EnableDocking ( CBRS_ALIGN_ANY ); this->EnableDocking ( CBRS_ALIGN_ANY );

this->DockControlBar( &m_toolbar, AFX_IDW_DOCKBAR_TOP ); return 0;

Khung cửa sổ giao diện chính 127

ƒ Hành vi InitInstance của CEmpApp sử dụng lớp CEmpFrame khai báo đối tượng cửa sổ chính của ứng dụng:

BOOL CEmpApp::InitInstance() {

CEmpFrame *main = new CEmpFrame; m_pMainWnd = main;

main->LoadFrame(IDR_MAINFRAME); main->ShowWindow(SW_SHOW); return TRUE;

}

2 Thực hành 5: Thực hiện ứng dụng tương tự VD31. Trong frame window, cài đặt cửa sổ view chứa dòng chữ chạy kiểu bảng chữ điện tử.

ƒ Tạo dự án VD32 tương tự VD31.

ƒ Bổ sung lớp CEmpView kế thừa từ CWnd. CEmpView đảm nhận việc hiển thị nội dung chữ chạy. Các cài đặt cần thiết như sau:

- Hành vi OnCreate thực hiện cài đặt timer:

int CEmpView::OnCreate(LPCREATESTRUCT lpCreateStruct) {

if (CWnd::OnCreate( lpCreateStruct) == -1 ) return -1;

SetTimer( ID_TIMER, 300, NULL ); // Interval = 300ms return 0;

}

- Hành vi OnDestroy hủy bỏ timer: void CEmpView::OnDestroy() {

KillTimer( ID_TIMER ); CWnd::OnDestroy(); }

- Hành vi OnTimer kích hoạt OnPaint:

void CEmpView::OnTimer(UINT nIDEvent) {

if (nIDEvent == ID_TIMER) {

Invalidate(); // Generates a WM_PAINT }

CWnd::OnTimer(nIDEvent); }

128Lập trình Windows với MFC - Microsoft Visual C++ 6.0 - Lê Ngọc Thạnh - lntmail@yahoo.com

- Hành vi OnPaint thực hiện vẽ chữ chạy: void CEmpView::OnPaint()

{

static char mess[] = "Chao cac ban ! "; char ch;

UINT i;

CPaintDC dc(this); // device context for painting ch = mess[0];

for (i=0; i < strlen(mess)-1; i++) mess[i] = mess[i+1]; mess[i] = ch; (adsbygoogle = window.adsbygoogle || []).push({});

dc.TextOut(10, 10, mess, 15); }

ƒ Dùng lớp CEmpView khai báo đối tượng view trong CEmpFrame: - Bổ sung thuộc tính protected m_view thuộc lớp CEmpView vào lớp

CEmpFrame.

- Hành vi OnCreate của CEmpFrame thực hiện khởi tạo thông số phù hợp cho đối tượng m_view; dùng số hiệu cho m_view là AFX_IDW_PANE_FIRST (view mặc nhiên của frame)

int CEmpFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {

... // Như cài đặt của VD31

m_view.Create ( NULL, NULL, AFX_WS_DEFAULT_VIEW, CRect(0,0,0,0), this, AFX_IDW_PANE_FIRST); return 0;

}

- Hành vi PreCreateWindow thực hiện hủy thông số ấn định dạng "chìm xuống" cho vùng client (chứa view – to get a nice look): BOOL CEmpFrame::PreCreateWindow(CREATESTRUCT& cs) {

if (!CFrameWnd::PreCreateWindow(cs)) return FALSE;

cs.dwExStyle &= ~WS_EX_CLIENTEDGE; return TRUE;

}

Khung cửa sổ giao diện chính 129

2 Thực hành 6: Thực hiện ứng dụng như VD32. Khi chọn mục Start của menu thì màn hình view thực hiện chữ chạy, đồng thời nội dung mục chuyển thành Stop. Nếu người dùng chọn lại mục này (Stop), hoạt động chạy chữ dừng lại và nội dung mục chọn chuyển thành Start.

ƒ Tạo dự án VD33 tương tự VD32.

ƒ Bổ sung thuộc tính m_isRun kiểu BOOL cho lớp CEmpView. m_isRun sẽ làm cờ hiệu cho chữ chạy. Một số chỉnh sửa sau của CEmpView: - Khởi đầu ấn định không chạy chữ:

int CEmpView::OnCreate(LPCREATESTRUCT lpCreateStruct) {

if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;

isRun = FALSE; // no animation SetTimer( ID_TIMER, 300, NULL );

return 0; }

- Hành vi OnTimer() dựa trên m_isRun để hành động: void CEmpView::OnTimer(UINT nIDEvent) {

if (nIDEvent == ID_TIMER) {

if ( isRun ) Invalidate(); // animation allowed ? }

CWnd::OnTimer(nIDEvent); }

- Bổ sung hành vi trả lời WM_COMMAND phát sinh bởi mục chọn ID_GAME_START (Start/Stop) trên menu. Đồng thời điều chỉnh nội dung mục thông báo của menu cho phù hợp:

void CEmpView::OnGameStart() {

isRun = !isRun;

CMenu *theMenu = GetParent()->GetMenu(); theMenu->ModifyMenu(ID_GAME_START,

MF_BYCOMMAND, ID_GAME_START,

(isRun)? "&Stop" : "&Start" ); } (adsbygoogle = window.adsbygoogle || []).push({});

ƒ Bổ sung hành vi OnCmdMsg cho CEmpFrame để chuyển các message WM_COMMAND cho m_view: m_view trong lớp CEmpFrame chỉ là cửa sổ con, không trực tiếp nhận WM_COMMAND từ menu cửa sổ cha.

130Lập trình Windows với MFC - Microsoft Visual C++ 6.0 - Lê Ngọc Thạnh - lntmail@yahoo.com

BOOL CEmpFrame::OnCmdMsg (

UINT nID, int nCode, void *pExtra,

AFX_CMDHANDLERINFO *pHandlerInfo ) {

// Dispatch command messages to m_view

if (m_view.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo)) return TRUE; // message was processed by m_view return CFrameWnd::OnCmdMsg ( nID, nCode, pExtra,

pHandlerInfo );

}

10.5.3 Dùng MFC wizard tạo ứng dụng với giao diện chính framewindow: Để người dùng có ngay một dự án cỡ VD32 mà không phải mất công thực hiện các công việc như trên, MFC wizard cung cấp chức năng hỗ trợ tạo nhanh dự án với cửa sổ chính là một frame window. Cách sử dụng chức năng hỗ trợ này như sau:

ƒ Chọn menu File / New.

Khung cửa sổ giao diện chính 131

ƒ Ấn định như trên. Chọn Next.

ƒ Ấn định như trên. Chọn Next.

132Lập trình Windows với MFC - Microsoft Visual C++ 6.0 - Lê Ngọc Thạnh - lntmail@yahoo.com

ƒ Chọn Next.

Khung cửa sổ giao diện chính 133

ƒ Chọn cơ chế liên kết với thư viện MFC. Sau đó chọn Next. ƒ Cuối cùng, ấn định tên tập tin chứa khai báo các lớp. Chọn Finish. THỰC HAØNH:

1. Tương tự VD33. Khi người dùng chọn mục Option thì hiển thị dialog với hai mục nhập: nội dung chuỗi chạy và tốc độ chạy chữ. Nếu người dùng click chọn OK thì thông tin nhập trong dialog sẽ được áp dụng cho dòng chữ chạy trong view.

2. Tương tự VD33. Thay hộp hiển thị câu thông báo "Mr.Emp" bằng một chiếc đồng hồ có dạng hh:mm:ss chạy theo thời gian lưu trong máy.

HD: Cài timer cho CEmpFrame. Sử dụng CTime của MFC (xem VD34). 3. Cài đặt mục progressbar trên thanh statusbar

của ứng dụng.

4. Viết ứng dụng với dialog giao diện chính có thanh trạng thái.

5. Viết ứng dụng với dialog giao diện chính có thanh công cụ và thanh trạng thái.

6. Quan sát trò chơi line. Phân tích và thực hiện ứng dụng này trong VC.

134 Lập trình Windows với MFC - Microsoft Visual C++ 6.0 - Lê Ngọc Thạnh - lntmail@yahoo.com

CHƯƠNG 11:

Một phần của tài liệu Lập trình Windows với MFC Microsoft Visual C++ 6.0 pdf (Trang 71 - 77)