Một số vấn đề trong windows
12.1 TẬP TIN INI:
Tập tin INI là tập tin văn bản chứa các nội dung phục vụ cho hoạt động của ứng dụng trong môi trường windows phiên bản 3.x và 9x. Các nội dung này được chia thành các thành phần (section) phân biệt theo chức năng hoặc theo nhóm ứng dụng con. Mỗi thành phần chứa các mục với tên gọi xác định và phân biệt với các mục khác trong cùng thành phần. Mỗi mục tương ứng với một giá trị duy nhất. Giá trị của mục được viết ngay sau tên mục, và được ngăn cách với tên mục bằng dấu "=".
Xét ví dụ là tập tin WIN.INI nói trên:
- windows : Tên thành phần (section). - NullPort : Tên mục (entry).
- None : Giá trị của mục NullPort.
Việc truy xuất giá trị các mục trong tập tin INI được hỗ trợ bởi lớp đối tượng quản lý ứng dụng CWinApp thông qua các thuộc tính, hành vi sau:
const char* m_pszAppName : Lưu chuỗi tên của ứng dụng. Giá trị thuộc tính này có thể được thay đổi được như sau:
free( (void*) m_pszAppName ); // Giải phóng vùng nhớ m_pszAppName =_tcsdup( _T(“Tên_mới_của_ứng_dụng”) );
Một số vấn đề trong Windows 159
const char* m_pszProfileName : Lưu đường dẫn và tên tập tin INI sử dụng bởi ứng dụng. Có thể thay đổi giá trị này để ấn định tập tin INI: free((void*)m_pszProfileName); // Hủy bỏ vùng nhớ cấp phát m_pszProfileName=_tcsdup(_T(“ĐườngDẫn-TênTậpTin_INI”)); BOOL WriteProfileString (
LPCTSTR lpszSection, // Tên thành phần LPCTSTR lpszEntry, // Tên mục
LPCTSTR lpszValue // Giá trị của mục (kiểu chuỗi) ); Lưu giá trị kiểu chuỗi của một mục trong thành phần xác định. BOOL WriteProfileInt (
LPCTSTR lpszSection, // Tên thành phần LPCTSTR lpszEntry, // Tên mục
int nValue // Giá trị của mục (số nguyên) ); Lưu giá trị kiểu số nguyên của một mục trong thành phần xác định. BOOL WriteProfileBinary (
LPCTSTR lpszSection, // Tên thành phần LPCTSTR lpszEntry, // Tên mục
LPBYTE pData, // Vùng đệm chứa giá trị mã UINT nBytes // Kích thước vùng đệm ); Lưu khối mã nhị phân của một mục trong thành phần xác định. CString GetProfileString (
LPCTSTR lpszSection, // Tên thành phần
LPCTSTR lpszEntry, // Tên mục. Nếu mục đọc không LPCTSTR lpszDefault = NULL // có thì sử dụng giá trị này. ); Trả về giá trị kiểu chuỗi của một mục trong thành phần tương ứng. UINT GetProfileInt (
LPCTSTR lpszSection, // Tên thành phần
LPCTSTR lpszEntry, // Tên mục. Nếu mục đọc không int nDefault // có thì sử dụng giá trị này. ); Trả về giá trị kiểu số nguyên của một mục trong thành tương ứng. BOOL GetProfileBinary (
LPCTSTR lpszSection, // Tên thành phần LPCTSTR lpszEntry, // Tên mục
LPBYTE *pData, // Địa chỉ con trỏ vùng đệm UINT *nBytes // Địa chỉ biến nhận kích thước. ); Đọc khối mã nhị phân của một mục vào vùng đệm.
160 Lập trình Windows với MFC - Microsoft Visual C++ 6.0 - Lê Ngọc Thạnh - lntmail@yahoo.com
Hành vi trả về giá trị TRUE nếu tác vụ đọc thành công.
Với: pData : Địa chỉ biến con trỏ quản lý vùng đệm nhận thông tin. nBytes : Địa chỉ biến chứa kích thước thông tin đọc được. ) Ứng dụng cần giải phóng vùng đệm pData khi chấm dứt sử dụng. 2 Đoạn chương trình sau thực hiện ghi xuống thành phần MY_TEST của tập tin INI của ứng dụng: MyName = Mr.Emp và MyVer = 11. CWinApp* pApp = AfxGetApp(); // Đối tượng quản lý ứng dụng pApp->WriteProfileString ("MY_TEST", "MyName", "Mr.Emp"); pApp->WriteProfileInt ("MY_TEST", "MyVer", 11);
2 Đoạn chương trình sau thực hiện đọc từ thành phần MY_TEST của tập tin INI giá trị hai mục nói trên.
CWinApp* pApp = AfxGetApp(); // Đối tượng quản lý ứng dụng CString myName = pApp->GetProfileString (
"MY_TEST", "MyName", "Mr.Emp" ); UINT myVer = pApp->GetProfileInt ("MY_TEST", "MyVer", 11); 12.2 SYSTEM REGISTRY:
System Registry là cơ sở dữ liệu do windows quản lý, được sử dụng để lưu trữ các nội dung phục vụ cho hoạt động của hệ thống và các ứng dụng. System registry có cấu trúc như sau (chương trình RegEdit.exe).
(System registry ở một máy sử dụng phiên bản Windows-Me )
Một số vấn đề trong Windows 161
- Mỗi mục trong cấu trúc cây (tree) gọi là khóa (key). - Khóa lá (không có con) là thành phần chứa các mục.
- Mỗi mục có một tên để nhận biết và có một giá trị xác định.
) Hành vi SetRegistryKey của lớp đối tượng CWinApp cho phép định hướng việc đọc/ghi giá trị các mục lên system registry thay vì sử dụng tập tin INI như (12.1). Hành vi loại protected này có cú pháp như sau:
void SetRegistryKey ( UINT lpszRegistryKey );
lpszRegistryKey : Thông thường là chuỗi chứa tên hãng phần mềm; ví dụ Netscape. Giá trị này trở thành khóa con của khóa Software thuộc khóa gốc HKEY_CURRENT_USER trong system registry.
) Khi ứng dụng thực hiện đọc/ghi giá trị mục, tên của ứng dụng (lưu trong m_pszAppName của đối tượng ứng dụng) trở thành khóa con của khóa xác định bởi lpszRegistryKey, và các thành phần chứa các mục trở thành khóa con của khóa m_pszAppName. Một thứ tự được thiết lập như sau:
HKEY_CURRENT_USER\Software\<Tên_hãng_phần_mềm>\ <Tên_ứng_dụng>\<Tên_thành_phần>\<Các_mục>. 2 Thực hiện ứng dụng IniReg. Ứng dụng đăng ký sử dụng system registry
với khóa "Mr.Emp", đồng thời tiến hành các tác vụ đọc / ghi hai giá trị như ví dụ mục (12.1).
Sau đây là các bước thực hiện dự án của ứng dụng:
Dùng MFC Wizard tạo dự án IniReg với giao diện chính là dialog. Hành vi InitInstance của lớp đối tượng quản lý ứng dụng thực hiện đặt
lại tên cho ứng dụng và đăng ký sử dụng registry với khóa "Mr.Emp": BOOL CIniRegApp::InitInstance()
{
free((void*)m_pszAppName); // Giải phóng vùng nhớ m_pszAppName=_tcsdup( _T("IniReg") ); // Đặt tên ứng dụng SetRegistryKey( _T("Mr.EMP") ); // Đăng ký registry CIniRegDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal(); // Thực hiện giao diện return TRUE;
}
Thực hiện các bổ sung sau cho lớp dialog giao diện CIniRegDlg: - Mở dialog resource, cài đặt các control sau:
162 Lập trình Windows với MFC - Microsoft Visual C++ 6.0 - Lê Ngọc Thạnh - lntmail@yahoo.com
- Hộp nhập giá trị mục MyName Edit IDC_WRITE_NAME - Hộp nhập giá trị mục MyVer Edit IDC_WRITE_VERSION - Hộp hiển thị mục MyName Static IDC_READ_NAME - Hộp hiển thị mục MyVer Static IDC_READ_VERSION - Nút chọn thực hiện ghi Button IDC_WRITE
- Nút chọn thực hiện đọc Button IDC_READ
- Hành vi OnWrite ứng với nút IDC_WRITE lưu giá trị các mục: void CIniRegDlg::OnWrite()
{
CWinApp* pApp = AfxGetApp(); CString myName;
UINT myVer;
GetDlgItemText(IDC_WRITE_NAME, myName); myVer = GetDlgItemInt(IDC_WRITE_VERSION);
pApp->WriteProfileString("MY_TEST", "MyName", myName); pApp->WriteProfileInt("MY_TEST", "MyVer", myVer);
}
- Hành vi OnRead ứng với nút IDC_READ đọc giá trị các mục: void CIniRegDlg::OnRead()
{
CWinApp* pApp = AfxGetApp(); CString myName;
UINT myVer;
myName = pApp->GetProfileString( "MY_TEST",
"MyName", "NoName" ); myVer = pApp->GetProfileInt( "MY_TEST", "MyVer", 0 ); SetDlgItemText( IDC_READ_NAME, myName );
SetDlgItemInt( IDC_READ_VERSION, myVer ); }
Biên dịch và chạy ứng dụng.