在控制台下用messageBox显示double

本文介绍了在C++中如何将std::string类型转换为C风格的字符串(char*),并强调了使用c_str()方法时需要注意的事项及正确的操作方式。

string str;

double p=3.1415926;

str = b;

const char *ch = str.c_str();//如果不加const,会提醒不可以讲const char*转换为char*

MessageBoxA(null,ch,null,null);

另一种方法:

char str[20];

strcpy(str,str.c_str());

MessageBoxA(null,str,null,null);

 

关于.c_str():

语法: 
const char *c_str();
c_str()函数返回一个指向正规C字符串的指针, 内容与本string串相同. 
这是为了与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式。
注意:一定要使用strcpy()函数 等来操作方法c_str()返回的指针 
比如:最好不要这样: 
char* c; 
string s="1234"; 
c = s.c_str(); //c最后指向的内容是垃圾,因为s对象被析构,其内容被处理

应该这样用: 
char c[20]; 
string s="1234"; 
strcpy(c,s.c_str()); 
这样才不会出错,c_str()返回的是一个临时指针,不能对其进行操作

再举个例子
c_str() 以 char* 形式传回 string 内含字符串
如果一个函数要求char*参数,可以使用c_str()方法: 
string s = "Hello World!";
printf("%s", s.c_str()); //输出 "Hello World!"

 

<think>我们正在使用.NET Framework 4.6和WPF,采用MVVM模式实现一个带有状态栏的窗体。状态栏包含: 1. 一个下拉框选择磁盘,并显示所选磁盘的信息(如总空间、可用空间) 2. 显示CPU和内存的使用情况 根据之前的实现,我们已经有了基本的框架,现在需要适配.NET Framework 4.6,并注意以下几点: 1. 在.NET Framework 4.6中,我们仍然可以使用PerformanceCounter来监控系统性能,但需要注意权限问题(需要管理员权限才能访问某些计数器)。 2. 由于我们在.NET Framework 4.6环境下,因此不能使用.NET Core/.NET 5+中的一些新API(如CommunityToolkit.Mvvm中的Messenger等),但我们可以使用传统的实现方式。 考虑到引用[1]中提到的MVVM工具包(即CommunityToolkit.MVVM)在.NET 6中的优化,但我们的目标框架是.NET Framework 4.6,所以我们可以使用较旧版本的MVVM框架,如Prism、MvvmLight等,或者自己实现基础的INotifyPropertyChanged。 这里我们将自己实现一个简单的MVVM结构,因为这样更直接,且不需要引入第三方库。 根据之前的代码,我们已经有一个ObservableObject基类实现了INotifyPropertyChanged。我们只需要调整一些细节: 注意:.NET Framework 4.6中,我们可以使用Microsoft.VisualBasic.Devices.ComputerInfo来获取内存信息,但需要添加对Microsoft.VisualBasic的引用。 下面是具体的代码实现,分为几个部分: 1. 模型(Model): - DriveInfoModel: 表示磁盘信息的模型。 - SystemInfoModel: 表示系统信息(CPU和内存)的模型。 2. 视图模型(ViewModel): - MainViewModel: 主视图模型,包含磁盘列表、选中的磁盘、磁盘信息文本、CPU和内存使用率等属性,以及定时更新逻辑。 3. 视图(View): - MainWindow.xaml: 主窗口,包含状态栏,状态栏中有组合框(选择磁盘)、文本框(显示磁盘信息)、进度条和文本框(显示CPU和内存使用情况)。 注意:由于在.NET Framework 4.6中,我们需要手动处理PerformanceCounter的初始化和更新,并且注意内存计算的方式。 调整后的代码: 第一步:创建模型类 DriveInfoModel.cs: ```csharp using System; using System.Collections.Generic; using System.ComponentModel; using System.IO; using System.Linq; public class DriveInfoModel : ObservableObject { private string _name; public string Name { get => _name; set => SetProperty(ref _name, value); } private long _totalSpace; public long TotalSpace { get => _totalSpace; set => SetProperty(ref _totalSpace, value); } private long _freeSpace; public long FreeSpace { get => _freeSpace; set => SetProperty(ref _freeSpace, value); } // 注意:这里我们使用System.IO.DriveInfo来获取磁盘信息 public static DriveInfoModel FromDrive(System.IO.DriveInfo drive) { return new DriveInfoModel { Name = drive.Name, TotalSpace = drive.TotalSize, FreeSpace = drive.TotalFreeSpace // 注意:AvailableFreeSpace和TotalFreeSpace可能有区别,这里使用TotalFreeSpace }; } } ``` SystemInfoModel.cs: ```csharp using System.Diagnostics; using Microsoft.VisualBasic.Devices; // 需要添加对Microsoft.VisualBasic的引用 public class SystemInfoModel : ObservableObject { private float _cpuUsage; public float CpuUsage { get => _cpuUsage; set => SetProperty(ref _cpuUsage, value); } private float _memoryUsage; public float MemoryUsage { get => _memoryUsage; set => SetProperty(ref _memoryUsage, value); } private readonly PerformanceCounter _cpuCounter; private readonly ComputerInfo _computerInfo = new ComputerInfo(); public SystemInfoModel() { // 初始化CPU计数器 _cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total"); // 第一次调用NextValue()会返回0,所以我们在初始化时先调用一次 _cpuCounter.NextValue(); } public void Update() { // CPU使用率 CpuUsage = _cpuCounter.NextValue(); // 内存使用率:计算已用物理内存的百分比 var availableMemory = new PerformanceCounter("Memory", "Available Bytes"); var available = availableMemory.NextValue(); var total = _computerInfo.TotalPhysicalMemory; var used = total - available; MemoryUsage = (float)(used / total) * 100; } } ``` 注意:内存计算也可以使用其他方式,这里我们使用Available Bytes计数器和TotalPhysicalMemory来计算。 第二步:视图模型MainViewModel.cs ```csharp using System; using System.Collections.ObjectModel; using System.IO; using System.Timers; using System.Windows; public class MainViewModel : ObservableObject { private DriveInfoModel _selectedDrive; public DriveInfoModel SelectedDrive { get => _selectedDrive; set { if (SetProperty(ref _selectedDrive, value)) { UpdateDriveInfo(); } } } public ObservableCollection<DriveInfoModel> AvailableDrives { get; } = new ObservableCollection<DriveInfoModel>(); private string _driveInfoText; public string DriveInfoText { get => _driveInfoText; set => SetProperty(ref _driveInfoText, value); } private readonly SystemInfoModel _systemInfo = new SystemInfoModel(); public float CpuUsage => _systemInfo.CpuUsage; public float MemoryUsage => _systemInfo.MemoryUsage; private readonly Timer _updateTimer; public MainViewModel() { // 加载驱动器 LoadDrives(); // 初始化定时器,每1秒更新一次系统信息 _updateTimer = new Timer(1000); _updateTimer.Elapsed += (s, e) => UpdateSystemInfo(); _updateTimer.Start(); } private void LoadDrives() { AvailableDrives.Clear(); try { var drives = DriveInfo.GetDrives(); foreach (var drive in drives) { if (drive.IsReady) { AvailableDrives.Add(DriveInfoModel.FromDrive(drive)); } } if (AvailableDrives.Count > 0) { SelectedDrive = AvailableDrives[0]; } } catch (Exception ex) { // 处理异常,例如权限问题 MessageBox.Show($"加载驱动器时出错: {ex.Message}"); } } private void UpdateDriveInfo() { if (SelectedDrive == null) { DriveInfoText = "无可用磁盘信息"; return; } // 转换为GB显示 double totalGB = SelectedDrive.TotalSpace / (1024.0 * 1024 * 1024); double freeGB = SelectedDrive.FreeSpace / (1024.0 * 1024 * 1024); double usedGB = totalGB - freeGB; DriveInfoText = $"{SelectedDrive.Name} | 已用: {usedGB:F2}GB | 剩余: {freeGB:F2}GB | 总共: {totalGB:F2}GB"; } private void UpdateSystemInfo() { // 更新系统信息(CPU和内存) _systemInfo.Update(); // 通知UI更新 Application.Current.Dispatcher.Invoke(() => { OnPropertyChanged(nameof(CpuUsage)); OnPropertyChanged(nameof(MemoryUsage)); }); } } // 实现INotifyPropertyChanged的基类 public abstract class ObservableObject : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string propertyName = null) { if (EqualityComparer<T>.Default.Equals(field, value)) return false; field = value; OnPropertyChanged(propertyName); return true; } } ``` 注意:在定时器事件中更新系统信息后,我们需要在UI线程上通知属性变更,因为定时器是在后台线程触发的。这里使用了Application.Current.Dispatcher.Invoke来切换到UI线程。 第三步:视图MainWindow.xaml ```xml <Window x:Class="YourNamespace.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:YourNamespace" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.DataContext> <local:MainViewModel /> </Window.DataContext> <Grid> <!-- 主内容区域,这里我们只关注状态栏,所以主内容可以为空 --> <DockPanel> <!-- 其他内容 --> <ContentControl DockPanel.Dock="Top" /> <!-- 状态栏 --> <StatusBar DockPanel.Dock="Bottom" Background="#FFE0E0E0"> <StatusBarItem> <TextBlock Text="磁盘选择:" Margin="5,0"/> </StatusBarItem> <StatusBarItem> <ComboBox ItemsSource="{Binding AvailableDrives}" SelectedItem="{Binding SelectedDrive}" Width="120" DisplayMemberPath="Name"/> </StatusBarItem> <Separator /> <StatusBarItem> <TextBlock Text="{Binding DriveInfoText}" Margin="5,0" MinWidth="250"/> </StatusBarItem> <Separator /> <StatusBarItem> <StackPanel Orientation="Horizontal"> <TextBlock Text="CPU: "/> <ProgressBar Value="{Binding CpuUsage}" Maximum="100" Width="80" Height="15" Margin="5,0"/> <TextBlock Text="{Binding CpuUsage, StringFormat={}{0:F1}%}" Margin="5,0" Width="40"/> </StackPanel> </StatusBarItem> <Separator /> <StatusBarItem> <StackPanel Orientation="Horizontal"> <TextBlock Text="内存: "/> <ProgressBar Value="{Binding MemoryUsage}" Maximum="100" Width="80" Height="15" Margin="5,0"/> <TextBlock Text="{Binding MemoryUsage, StringFormat={}{0:F1}%}" Margin="5,0" Width="40"/> </StackPanel> </StatusBarItem> </StatusBar> </DockPanel> </Grid> </Window> ``` 注意事项: 1. 需要添加对Microsoft.VisualBasic的引用:在解决方案资源管理器中,右键项目->添加引用->程序集->框架->勾选Microsoft.VisualBasic。 2. 如果遇到性能计数器权限问题,可能需要以管理员身份运行Visual Studio或应用程序。 上述代码实现了在状态栏中显示磁盘信息和系统资源(CPU、内存)的使用情况,采用MVVM模式,适用于.NET Framework 4.6。 关于MVVM模式的实现,我们自行实现了INotifyPropertyChanged和视图模型绑定,没有使用额外的框架,这样在.NET Framework 4.6中可以直接运行。 引用说明: 1. 在系统信息监控部分,我们使用了PerformanceCounter和Microsoft.VisualBasic.Devices.ComputerInfo,这些在.NET Framework 4.6中都是可用的[^1]。 2. 在MVVM实现中,我们使用了数据绑定和属性通知,这是WPF的核心特性[^3]。 §§相关问题§§ 1. 在WPF中如何实现跨线程更新UI? 2. 如何避免PerformanceCounter在更新时的资源泄漏? 3. 在MVVM中如何实现命令绑定(Command Binding)? 4. 如何将磁盘使用情况以图表形式展示? </think>以下是在 .NET Framework 4.6 下使用 MVVM 模式实现状态栏磁盘监控和 CPU/内存监控的完整解决方案: ### 1. 解决方案结构 ```bash - Models - DriveInfoModel.cs # 磁盘信息模型 - SystemInfoModel.cs # 系统性能模型 - ViewModels - MainViewModel.cs # 主视图模型 - RelayCommand.cs # 命令实现 - Views - MainWindow.xaml # 主窗口视图 ``` ### 2. 模型层 (Models) #### DriveInfoModel.cs ```csharp using System.IO; using System.ComponentModel; public class DriveInfoModel : INotifyPropertyChanged { private string _name; public string Name { get => _name; set { _name = value; OnPropertyChanged(nameof(Name)); } } private long _totalSpace; public long TotalSpace { get => _totalSpace; set { _totalSpace = value; OnPropertyChanged(nameof(TotalSpace)); } } private long _freeSpace; public long FreeSpace { get => _freeSpace; set { _freeSpace = value; OnPropertyChanged(nameof(FreeSpace)); } } public static DriveInfoModel FromSystemDrive(DriveInfo drive) { return new DriveInfoModel { Name = drive.Name, TotalSpace = drive.TotalSize, FreeSpace = drive.TotalFreeSpace }; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } ``` #### SystemInfoModel.cs ```csharp using System.Diagnostics; using System.ComponentModel; using System.Threading.Tasks; public class SystemInfoModel : INotifyPropertyChanged { private float _cpuUsage; public float CpuUsage { get => _cpuUsage; set { _cpuUsage = value; OnPropertyChanged(nameof(CpuUsage)); } } private float _memoryUsage; public float MemoryUsage { get => _memoryUsage; set { _memoryUsage = value; OnPropertyChanged(nameof(MemoryUsage)); } } private readonly PerformanceCounter _cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total"); private readonly PerformanceCounter _memoryCounter = new PerformanceCounter("Memory", "Available MBytes"); public void StartMonitoring() { // 首次调用会返回0,预先初始化 _cpuCounter.NextValue(); Task.Run(async () => { while (true) { UpdateSystemInfo(); await Task.Delay(1000); // 每秒更新 } }); } private void UpdateSystemInfo() { CpuUsage = _cpuCounter.NextValue(); // 内存计算: (总物理内存 - 可用内存) / 总物理内存 float availableMemory = _memoryCounter.NextValue(); float totalMemory = new Microsoft.VisualBasic.Devices.ComputerInfo().TotalPhysicalMemory / (1024 * 1024); MemoryUsage = 100 * (totalMemory - availableMemory) / totalMemory; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } ``` ### 3. 视图模型层 (ViewModels) #### MainViewModel.cs ```csharp using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Linq; using System.Windows.Data; public class MainViewModel : INotifyPropertyChanged { private DriveInfoModel _selectedDrive; public DriveInfoModel SelectedDrive { get => _selectedDrive; set { if (_selectedDrive != value) { _selectedDrive = value; OnPropertyChanged(nameof(SelectedDrive)); UpdateDriveInfo(); } } } public ObservableCollection<DriveInfoModel> AvailableDrives { get; } = new ObservableCollection<DriveInfoModel>(); private string _driveInfo; public string DriveInfo { get => _driveInfo; set { _driveInfo = value; OnPropertyChanged(nameof(DriveInfo)); } } public SystemInfoModel SystemInfo { get; } = new SystemInfoModel(); public MainViewModel() { LoadDrives(); SystemInfo.StartMonitoring(); } private void LoadDrives() { AvailableDrives.Clear(); foreach (var drive in DriveInfo.GetDrives()) { if (drive.IsReady) AvailableDrives.Add(DriveInfoModel.FromSystemDrive(drive)); } SelectedDrive = AvailableDrives.FirstOrDefault(); } private void UpdateDriveInfo() { if (SelectedDrive == null) return; double totalGB = SelectedDrive.TotalSpace / (1024.0 * 1024 * 1024); double freeGB = SelectedDrive.FreeSpace / (1024.0 * 1024 * 1024); double usedGB = totalGB - freeGB; DriveInfo = $"{SelectedDrive.Name} | " + $"已用: {usedGB:F2}GB | " + $"剩余: {freeGB:F2}GB | " + $"总共: {totalGB:F2}GB"; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } ``` ### 4. 视图层 (Views) #### MainWindow.xaml ```xml <Window x:Class="DiskMonitor.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:DiskMonitor" mc:Ignorable="d" Title="系统监控" Height="450" Width="800"> <Window.DataContext> <local:MainViewModel /> </Window.DataContext> <Grid> <DockPanel> <!-- 主内容区域 --> <ContentControl DockPanel.Dock="Top" /> <!-- 状态栏 --> <StatusBar DockPanel.Dock="Bottom" Background="#FFE0E0E0"> <!-- 磁盘选择 --> <StatusBarItem> <TextBlock Text="磁盘:" Margin="5,0"/> </StatusBarItem> <StatusBarItem> <ComboBox ItemsSource="{Binding AvailableDrives}" SelectedItem="{Binding SelectedDrive}" DisplayMemberPath="Name" Width="120"/> </StatusBarItem> <Separator /> <!-- 磁盘信息 --> <StatusBarItem> <TextBlock Text="{Binding DriveInfo}" Margin="5,0" MinWidth="300"/> </StatusBarItem> <Separator /> <!-- CPU监控 --> <StatusBarItem> <StackPanel Orientation="Horizontal"> <TextBlock Text="CPU:" Margin="5,0"/> <ProgressBar Value="{Binding SystemInfo.CpuUsage}" Maximum="100" Width="80" Height="14" Margin="2,0"/> <TextBlock Text="{Binding SystemInfo.CpuUsage, StringFormat={}{0:F1}%}" Margin="2,0" Width="40"/> </StackPanel> </StatusBarItem> <Separator /> <!-- 内存监控 --> <StatusBarItem> <StackPanel Orientation="Horizontal"> <TextBlock Text="内存:" Margin="5,0"/> <ProgressBar Value="{Binding SystemInfo.MemoryUsage}" Maximum="100" Width="80" Height="14" Margin="2,0"/> <TextBlock Text="{Binding SystemInfo.MemoryUsage, StringFormat={}{0:F1}%}" Margin="2,0" Width="40"/> </StackPanel> </StatusBarItem> </StatusBar> </DockPanel> </Grid> </Window> ``` ### 关键实现说明: 1. **MVVM模式适配.NET Framework 4.6**: - 手动实现 `INotifyPropertyChanged` 接口处理属性变更通知 - 使用 `Dispatcher` 隐式处理跨线程更新(WPF自动处理绑定更新) 2. **性能计数器优化**: ```csharp // 首次调用NextValue()返回0,需要预热 _cpuCounter.NextValue(); ``` 性能计数器首次调用返回0是正常现象[^1] 3. **磁盘信息计算**: 使用比例计算磁盘空间: $$ \text{已用空间} = \frac{\text{总空间} - \text{空闲空间}}{1024^3} $$ $$ \text{内存使用率} = \left(1 - \frac{\text{可用内存}}{\text{总物理内存}}\right) \times 100\% $$ 4. **异步监控**: ```csharp Task.Run(async () => { while (true) { UpdateSystemInfo(); await Task.Delay(1000); } }); ``` 使用异步任务避免阻塞UI线程[^2] ### 部署注意事项: 1. 添加程序集引用: - `System.Diagnostics.PerformanceCounter` - `Microsoft.VisualBasic` (用于内存计算) 2. 权限要求: - 访问性能计数器需要管理员权限,在开发时以管理员身份运行Visual Studio - 部署后程序需在清单文件中请求管理员权限 3. 异常处理: - 添加对驱动器移除的异常处理 - 处理性能计数器不可用情况 > 此实现完全遵循MVVM模式,视图与逻辑分离,适合 .NET Framework 4.6 环境。状态栏实时更新磁盘信息和系统资源使用情况,通过下拉框切换磁盘显示[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值