Danh mục

Các giải pháp lập trình CSharp- P71

Số trang: 10      Loại file: pdf      Dung lượng: 2.63 MB      Lượt xem: 3      Lượt tải: 0    
10.10.2023

Xem trước 2 trang đầu tiên của tài liệu này:

Thông tin tài liệu:

Các giải pháp lập trình CSharp- P71: Các giải pháp lập trình C# khảo sát chiều rộng của thư viện lớp .NET Framework và cung cấp giải pháp cụ thể cho các vấn đềthường gặp. Mỗi giải pháp được trình bày theo dạng “vấn đề/giải pháp” một cách ngắn gọn và kèm theo là các ví dụ mẫu.
Nội dung trích xuất từ tài liệu:
Các giải pháp lập trình CSharp- P71 591 Chương 15: Khả năng liên tác mã lệnh không-được-quản-lý private System.Windows.Forms.Label lblCaption; [DllImport(user32.dll)] private static extern int GetForegroundWindow(); [DllImport(user32.dll)] private static extern int GetWindowText(int hWnd, StringBuilder text, int count); private void tmrRefresh_Tick(object sender, System.EventArgs e) { int chars = 256; StringBuilder buff = new StringBuilder(chars); int handle = GetForegroundWindow(); if (GetWindowText(handle, buff, chars) > 0) { lblCaption.Text = buff.ToString(); lblHandle.Text = handle.ToString(); if (new IntPtr(handle) == this.Handle) { lblCurrent.Text = True; } else { lblCurrent.Text = False; } } }} Handle của form được quản lý một cách trong suốt đối với người dùng. Thay đổi thuộc tính nào đó của form có thể khiến cho CRL tạo một handle mới. Do đó, bạn nên luôn truy xuất handle ngay trước khi sử dụng nó (không nên giữ nó trong một biến để sử dụng trong một thời gian dài).3. Gọi một hàm không-được-quản-lý có sử dụng cấu trúc Bạn cần gọi một hàm không-được-quản-lý có thông số là một cấu trúc. Định nghĩa cấu trúc trong mã C#. Sử dụng đặc tính System.Runtime.InteropServices.StructLayoutAttribute để cấu hình việc cấp bộ nhớ cho cấu trúc. Sử dụng phương thức tĩnh SizeOf của lớp 592 Chương 15: Khả năng liên tác mã lệnh không-được-quản-lý System.Runtime.Interop.Marshal nếu muốn xác định kích thước của cấu trúc theo byte.Trong mã C# thuần túy, bạn không có khả năng trực tiếp kiểm soát việc cấp bộ nhớ. Thay vàođó, CRL sẽ quyết định khi nào cần đưa dữ liệu vào bộ nhớ để tối ưu hóa hoạt động. Điều nàygây rắc rối khi làm việc với các hàm C, vì cấu trúc phải được trữ liên tục trong bộ nhớ. Maymắn là .NET đã giải quyết vấn đề này bằng đặc tính StructLayoutAttribute, cho phép bạn chỉđịnh các thành viên của một lớp hay một cấu trúc cho trước sẽ được sắp xếp trong bộ nhớ nhưthế nào.Ví dụ, xét hàm GetVersionEx trong thư viện kernel32.dll. Hàm này nhận một con trỏ chỉ tớicấu trúc OSVERSIONINFO và sử dụng nó để trả về thông tin phiên bản của hệ điều hành. Để sửdụng cấu trúc OSVERSIONINFO trong mã C#, bạn phải định nghĩa nó với đặc tínhStructLayoutAttribute như sau:[StructLayout(LayoutKind.Sequential)]public class OSVersionInfo { public int dwOSVersionInfoSize; public int dwMajorVersion; public int dwMinorVersion; public int dwBuildNumber; public int dwPlatformId; [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] public String szCSDVersion;}Chú ý rằng, cấu trúc này cũng sử dụng đặc tính System.Runtime.InteropServices.MarshalAsAttribute (cần cho các chuỗi có kích thước không đổi). Ở đây,MarshalAsAttribute chỉ định chuỗi sẽ được truyền bằng trị và sẽ chứa một bộ đệm gồm 128ký tự được chỉ định trong cấu trúc OSVersionInfo. Trong ví dụ này, LayoutKind.Sequentialđược sử dụng, nghĩa là các kiểu dữ liệu trong cấu trúc được bố trí theo thứ tự mà chúng đượcliệt kê trong cấu trúc hoặc lớp.Ngoài LayoutKind.Sequential, bạn có thể sử dụng LayoutKind.Explicit. Trong trường hợpnày, bạn phải sử dụng FieldOffsetAttribute để định nghĩa độ dời của các trường. Cách nàyhữu ích khi bạn muốn lưu trữ các trường một cách linh động hơn, hoặc bạn muốn bỏ qua(không sử dụng) trường nào đó. Ví dụ sau định nghĩa lớp OSVersionInfo vớiLayoutKind.Explicit.[StructLayout(LayoutKind.Explicit)]public class OSVersionInfo { [FieldOffset(0)] public int dwOSVersionInfoSize; 593 Chương 15: Khả năng liên tác mã lệnh không-được-quản-lý [FieldOffset(4)] public int dwMajorVersion; [FieldOffset(8)] public int dwMinorVersion; [FieldOffset(12)] public int dwBuildNumber; [FieldOffset(16)] public int dwPlatformId; [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] [FieldOffset(20)] public String szCSDVersion;}Sau khi đã định nghĩa cấu trúc được sử dụng bởi hàm GetVersionEx, bạn có thể khai báo hàmnày và sử dụng nó. Ứng dụng dưới đây sẽ trình bày toàn bộ mã lệnh cần thiết. Chú ý,InAttribute và OutAttribute được áp dụng cho OSVersionInfo để biết rằng marshalling sẽđược thực hiện trên cấu trúc này khi nó được truyền cho hàm và khi nó được trả về từ hàm.Ngoài ra, phương thức Marshal.SizeOf được sử dụng để tính kích thước của cấu trúc trong bộnhớ.using System;using System.Runtime.InteropServices;public class CallWithStructure { // (Bỏ qua lớp OSVersionInfo.) [DllImport(kernel32.dll)] public static extern bool GetVersionEx([In, Out] OSVersionInfo osvi); private static void Main() { OSVersionInfo osvi = new OSVersionInfo(); osvi.dwOSVersionInfoSize = Marshal.SizeOf(osvi); GetVersionEx(osvi); Console.WriteLine(Class size: + osvi.dwOSVersionInfoSize); Console.WriteLine(Major Version: + osvi.dwMajorVersion); Console.WriteLine(Minor Version: + osvi.dwMinorVersion); Console.WriteLine(Build Number: + osvi.dwBuildNumber); Console.WriteLine(Platform Id: + osvi.dwPlatformId); Console.WriteLine(CSD Version: + osvi.szCSDVersion); Console.WriteLine(Platform: + Environment.OSVersion.Platform); Console.WriteLine( Version: + Environment.OSVersion.Version); Console.ReadLine(); } 594 Chương 15: Khả năng liên tác mã lệnh không-được-q ...

Tài liệu được xem nhiều: