Menu Trong Lập Trình C Trên Windows

MENU TRONG LẬP TRÌNH C TRÊN WINDOWS

Trong giao diện ứng dụng Windows, thành phần quan trọng thường không thể thiếu là menu của chương trình. Menu xuất hiện ngay dưới thanh tiêu đề của chương trình ứng dụng. Ngoài ra trong một số ứng dụng thanh menu có thể di chuyển được.
Thật ra menu cũng khá đơn giản, vì chúng được tổ chức thành các nhóm trên thanh chính (FileEditView,…), mỗi mục liệt kê trong menu chính có thể chứa một hay nhiều mục liệt kê gọi là menu popup hay dropdown, và với mỗi mục liệt kê trong menu popup này có thể có các mục con của nó,….
Các mục liệt kê trên menu có thể dùng để kích hoạt một lệnh, hay chọn trạng thái (checkuncheck). Các mục liệt kê trên menu có 3 dạng: có hiệu lực (enabled), không có hiệu lực (disabled), và màu xám (grayed). Với quan điểm lập trình thì ta chỉ cần hai trạng thái là có hiệu lực và không có hiệu lực mà thôi, do đó trạng thái màu xám sẽ chỉ cho người dùng biết là trạng thái của mục liệt kê có hiệu lực hay không. Vì vậy khi viết chương trình những mục nào không có hiệu lực thì ta thiết lập trạng thái màu xám, khi đó người dùng sẽ biết rằng mục liệt kê đó không có hiệu lực.

Thiết lập Menu

Để tạo một menu và đưa vào chương trình bao gồm các bước sau:
*Tạo menu trong tập tin tài nguyên *.RC: Để tạo menu trong tập tin tài nguyên, thường có 2 cách chính là: dùng một trình soạn thảo để mở tập tin tài nguyên và soạn thảo theo cấu trúc tập tin RC cung cấp cho tài nguyên menu. Thông thường, cách này ít sử dụng, vì các môi trường phát triển C trên Windows (Borland C for Windows, Visual C) đều cung cấp các công cụ cho phép tạo menu một cách dễ dàng.
*Cài đặt menu vào cửa sổ của chương trình ứng dụng: phần này đơn giản là khi định nghĩa lớp cửa sổ ta thiết lập thuộc tính lpszMenuName của cấu trúc lớp WNDCLASS bằng tên menu được khai báo trong tập tin tài nguyên.
Ví dụ : wndclass.lpszMenuName = "MENU1";
Ngoài ra, có thể cài đặt menu vào cửa sổ bằng cách dùng lệnh :
hMenu = LoadMenu ( hInstance, TEXT("MENU1") );
Lệnh này sẽ trả về một định danh của menu được nạp, khi có được định danh menu này thì khi đưa vào cửa sổ có 2 cách sau:
*Trong hàm tạo cửa sổ CreateWindow, tham số thứ 9 của hàm là định danh cho menu, thiết lập tham số này là định danh của menuvừa tạo.
hwnd = CreateWindow TEXT("MyClass"), TEXT("Window Caption"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, hMenu, hInstance, NULL );
*Khi gọi hàm tạo cửa sổ CreateWindow, tham số thứ 9 được thiết lập NULL, sau đó trong chương trình dùng lệnh: SetMenu(hWnd, hMenu); để thiết lập menu cho cửa sổ.
*Thêm các đoạn chương trình xử lý menu: Windows phát sinh thông điệp WM_COMMAND và gởi đến chương trình khi người dùng chọn một mục liệt kê có hiệu lực trên thanh menu. Khi đó chỉ cần xử lý thông điệp WM_COMMAND bằng cách kiểm tra 16 bit thấp của tham số wParam là xác định được ID của mục liệt kê nào trên menu được chọn.

Ví dụ minh họa Menu

*Tập tin tài nguyên chứa khai báo menu : MENUDEMO.RC
MENUDEMO MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "&New", IDM_FILE_NEW
MENUITEM "&Open", IDM_FILE_OPEN
MENUITEM "&Save", IDM_FILE_SAVE
MENUITEM "Save &As...", IDM_FILE_SAVE_AS
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_APP_EXIT
END
POPUP "&Edit"
BEGIN
MENUITEM "&Undo", IDM_EDIT_UNDO
MENUITEM SEPARATOR
MENUITEM "C&ut", IDM_EDIT_CUT
MENUITEM "&Copy", IDM_EDIT_COPY
MENUITEM "&Paste", IDM_EDIT_PASTE
MENUITEM "De&lete", IDM_EDIT_CLEAR
END
POPUP "&Background"
BEGIN
MENUITEM "&White", IDM_BKGND_WHITE, CHECKED
MENUITEM "&Light Gray", IDM_BKGND_LTGRAY
MENUITEM "&Gray", IDM_BKGND_GRAY
MENUITEM "&Dark Gray", IDM_BKGND_DKGRAY
MENUITEM "&Black", IDM_BKGND_BLACK
END
POPUP "&Help"
BEGIN
MENUITEM "&Help...", IDM_APP_HELP
MENUITEM "&About ...", IDM_APP_ABOUT
END
END
*Tập tin tiêu đề chứa các định nghĩa : MENUDEMO.H
#define IDM_FILE_NEW 40001
#define IDM_FILE_OPEN 40002
#define IDM_FILE_SAVE 40003
#define IDM_FILE_SAVE_AS 40004
#define IDM_APP_EXIT 40005
#define IDM_EDIT_UNDO 40006
#define IDM_EDIT_CUT 40007
#define IDM_EDIT_COPY 40008
#define IDM_EDIT_PASTE 40009
#define IDM_EDIT_CLEAR 40010
#define IDM_BKGND_WHITE 40011
#define IDM_BKGND_LTGRAY 40012
#define IDM_BKGND_GRAY 40013
#define IDM_BKGND_DKGRAY 40014
#define IDM_BKGND_BLACK 40015
#define IDM_APP_HELP 40018
#define IDM_APP_ABOUT 40019
*Tập tin chứa mã nguồn : MENUDEMO.C
#include <windows.h>
#include "menudemo.h"
LRESULTCALLBACK WndProc (HWNDUINTWPARAMLPARAM);
/* Khai báo tên dùng chung cho cáctài nguyên trong chương trình.*/
TCHAR szAppName[] = TEXT ("MenuDemo") ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground =
(HBRUSH)GetStockObject(WHITE_BRUSH) ;
wndclass.lpszMenuName = szAppName ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox(NULL, TEXT("This program requires Windows "), szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd = CreateWindow (szAppName, TEXT("Menu Demonstration"), WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULTCALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
/* Khao báo danh sách các màu chỗi tô, các hằng này được định nghĩa trong file WINGDI.H */
static int idColor[5] = { WHITE_BRUSH, LTGRAY_BRUSH, GRAY_BRUSH, DKGRAY_BRUSH, BLACK_BRUSH } ;
static int iSelection = IDM_BKGND_WHITE ;
HMENU hMenu ;
switch (message)
{
case WM_COMMAND:
hMenu = GetMenu (hwnd) ; // Lấy định danh của menu
switch (LOWORD (wParam)) // Kiểm tra định danh mục chọn
{
case IDM_FILE_NEW:
case IDM_FILE_OPEN:
case IDM_FILE_SAVE:
case IDM_FILE_SAVE_AS:
MessageBeep(0) ; //Phát ra tiếng kêu bíp
return 0 ;
case IDM_APP_EXIT:
/*Gởi thông điệp để đóng ứng dụng lại*/
SendMessage (hwnd, WM_CLOSE, 0, 0) ;
return 0 ;
case IDM_EDIT_UNDO:
case IDM_EDIT_CUT:
case IDM_EDIT_COPY:
case IDM_EDIT_PASTE:
case IDM_EDIT_CLEAR:
MessageBeep (0) ;
return 0 ;
case IDM_BKGND_WHITE:
case IDM_BKGND_LTGRAY:
case IDM_BKGND_GRAY:
case IDM_BKGND_DKGRAY:
case IDM_BKGND_BLACK:
/* Bỏ check của mục chọn trước đó*/
CheckMenuItem(hMenu,iSelection, MF_UNCHECKED);
iSelection = LOWORD (wParam) ; /*Lấy ID mục mới*/
/* Check mục chọn mới*/
CheckMenuItem (hMenu, iSelection, MF_CHECKED) ;
/* Thiết lập màu tương ứng với mục chọn mới*/
SetClassLong(hwnd,GCL_HBRBACKGROUND, (LONG) GetStockObject(idColor[iSelection-IDM_BKGND_WHITE]));
InvalidateRect (hwnd, NULL, TRUE) ;
return 0 ;
case IDM_APP_HELP:
MessageBox(hwnd, TEXT("Help not yet implemented!"), szAppName, MB_ICONEXCLAMATION | MB_OK) ;
return 0 ;
case IDM_APP_ABOUT:
MessageBox (hwnd, TEXT ("Menu Demonstration Program\n (c) Charles Petzold, 1998"), szAppName, MB_ICONINFORMATION | MB_OK) ;
return 0 ;
}
break;
case WM_DESTROY:
PostQuitMessage(0) ;
return 0 ;
}
return DefWindowProc(hwnd, message, wParam, lParam) ;
}

0 Comment:

Đăng nhận xét

Thank you for your comments!