- 博客(99)
- 收藏
- 关注
原创 C# 活动窗体截图:基于 Win32 API 的实现
该截图功能类基于BitBltGDI+user32.dlldwmapi.dllgdi32.dll返回窗口边框矩形(不含阴影等视觉扩展),而能获取实际显示区域,确保截图完整。BitBltBitBlt适用场景与限制BitBlt。
2025-05-15 16:27:49
317
原创 C#自定义控件-实现了一个支持平移、缩放、双击重置的图像显示控件
图像显示与缩放(支持鼠标滚轮缩放)图像平移(支持鼠标拖拽)视图重置(双击重置)网格背景显示。
2025-05-15 15:25:31
405
原创 C# 使用Windows API实现键盘钩子的类
主窗体需能访问此实例,建议将其存储在公共成员变量中(建议放在Program.cs)类实现(位于keyboard.cs)。:是否允许该按键传递到其他应用。接口,推荐在应用主程序中通过。当按键被拦截时,会触发。
2025-04-23 17:39:01
320
原创 C# byte[]字节数组常用的一些操作。
通过整数除法实现向上取整。+ 1:补偿截断的部分,确保结果向上取整。Length = 8→(正确)。Length = 9→(正确)。:直接数学向上取整。8.0强制浮点除法,保留小数部分。对结果向上取整。
2025-04-22 11:50:51
431
原创 C# 使用.NET内置的 IObservable<T> 和 IObserver<T>-观察者模式
表示(如事件流、实时数据)。,用于注册观察者。表示,响应数据变化。:接收新数据。:处理错误。:响应数据流结束。
2025-04-15 11:25:16
435
原创 软件设计模式
示例:跨平台的 UI 组件库(如 Windows/Mac 的按钮和文本框)。定义对象间的一对多依赖,当一个对象状态改变时,所有依赖者自动更新。示例:虚拟代理(延迟加载图片)、保护代理(权限控制)。示例:构造一个包含多种部件的复杂对象(如电脑组装)。示例:不同形状(圆形、方形)和颜色(红、蓝)的组合。示例:克隆一个配置好的对象(如游戏中的敌人复制)。关注对象的创建机制,提高代码的灵活性和可复用性。为其他对象提供一种代理以控制对这个对象的访问。将请求封装为对象,支持请求的排队、日志或撤销。
2025-04-15 09:28:13
584
原创 C#Task.ContinueWith 方法深度解析
Console.WriteLine($"异常: {t.Exception.InnerException.Message}");.ContinueWith(t => Console.WriteLine($"最终结果: {t.Result}"));task.ContinueWith(previousTask => { // 前置任务完成后执行的代码 });task.ContinueWith(t => Console.WriteLine("完成"),if (t.IsFaulted) { /* 处理异常 */ }
2025-04-10 11:48:07
753
原创 C# 关于 async 中直接调用 .Result死锁的问题
需要返回 UI 线程继续执行,但 UI 线程已经被阻塞,导致互相等待(死锁)。:UI 卡死,因为 WinForms 有同步上下文。等待 UI 线程空闲,而 UI 线程又在等待。不会阻塞 UI 线程,而是让 UI 线程在。期间去处理其他消息(如鼠标移动、按钮点击)。,无法处理其他消息(如界面渲染、用户输入)。,因为控制台程序没有 UI 同步上下文。(但不适用于 UI 更新)。阻塞了 UI 线程,而。在 1 秒后正常更新。
2025-04-10 09:03:29
457
原创 C#中获取字节数据的高字节和低字节
在C#中,你可以使用位操作来获取16位或更大数值的高字节和低字节部分。小端序(Little-Endian):低字节在前(x86架构)大端序(Big-Endian):高字节在前(网络字节序)对于32位整数(uint/int)
2025-03-25 16:12:21
578
原创 记录MFC联合halcon界面显示开发
要将 Halcon 的测试效果显示在 MFC 程序的界面中,你可以通过以下步骤实现。基本思路是在 MFC 窗口中创建一个合适的区域来显示 Halcon 处理后的图像和图形,通常可以使用CStatic控件作为显示区域,并通过 Halcon 的 C++ 接口(HalconCpp)将处理结果绘制到该区域上。:使用 Visual Studio 创建一个新的 MFC 对话框应用程序项目。CStatic:用于显示 Halcon 的处理结果。假设该控件的 ID 为。
2025-02-26 22:13:17
521
原创 C# 比较两个List集合内容是否相同
在 C# 中,要比较两个List<T>忽略顺序:可以先对两个列表排序后再使用。如果你想比较自定义对象的集合,比如,你需要自定义比较规则。默认情况下,List<T>的比较是基于对象引用的比较(即两个对象的引用是否相同),而不是根据对象的内容来判断。为了比较自定义元素,你需要重写Equals和方法。这样,比较时会依据你定义的规则进行比较。假设你有一个自定义类Person,你想根据Name和Age属性来判断两个Person对象是否相同。顺序和内容都相等:使用。忽略顺序。
2025-02-08 14:18:58
1197
原创 深入理解C#结构型设计模式:类适配器与对象适配器
适配器模式就是结构型设计模式中的一种,它允许将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。如果需要适配的类较多,或者希望降低类之间的耦合度,提高代码的灵活性,那么对象适配器模式更为合适。它创建一个新的类,该类持有需要适配的类的实例,并实现目标接口。在目标接口的方法中,调用适配类实例的相应方法。接口,将旧系统的支付方法适配到了新的接口上,使得旧系统可以无缝融入新的支付流程。方法中,根据文件的扩展名选择调用不同的读取器方法,实现了对多种文件读取器的适配。
2025-02-08 13:47:51
1173
原创 C# base关键字使用
在你的代码中,Animal类定义了一个带string因此,Dog类的构造函数就必须显式调用Animal类的这个构造函数,而使用base关键字就是显式调用基类构造函数的方式。
2025-02-08 11:47:54
523
原创 C# SQlite使用流程
3.按照如下流程新建数据表并设置列表 信息。1.打开sqlitestudio软件。2.按照如下流程新建DB数据库。,新建一个db数据库文件。
2025-02-07 15:45:59
272
原创 C# LiteDB 使用教程
通过本教程,你已经了解了 LiteDB 的基本使用方法,包括安装、创建数据库、数据建模、CRUD 操作、索引的使用和事务处理等。LiteDB 以其轻量级、嵌入式和易用性的特点,为开发者提供了一个高效的数据存储解决方案。在实际项目中,你可以根据具体需求进一步探索 LiteDB 的高级功能,如数据加密、文件存储等。希望本教程能帮助你更好地使用 LiteDB 进行数据管理。
2025-02-06 16:27:50
1298
原创 学习记录:C++宏定义包含多条语句,使用注意事项
在 C++ 中,如果多语句代码可以用函数实现,内联函数是更好的选择。内联函数具有函数的所有特性,如类型检查、作用域规则清晰等,同时在编译时可以像宏一样展开,减少函数调用开销。例如,在宏内声明一个临时变量用于计算,且不希望该变量影响宏外部的同名变量时,,宏展开后可能导致语法错误,因为条件语句只能控制紧随其后的一条语句,而宏展开后的多条语句会破坏这种结构。结构,但在大多数情况下,特别是当宏可能在条件语句或循环语句中使用时,使用。语句只控制了花括号内的第一条语句(变量声明),后面的赋值语句不受。
2025-01-09 09:55:05
546
原创 学习记录:C/C++ 中的续行符
计算球体的表面积和体积。球体表面积公式为 S=4πr²,我们可以通过宏定义来简化这些计算。// 定义圆周率宏// 使用续行符定义球体表面积宏在上述代码中,宏定义使用了续行符将复杂的数学表达式拆分成多行。这样,代码在视觉上更加清晰,我们可以轻松地看到宏定义的各个部分,理解其计算逻辑。在某些情况下,宏定义可能不仅仅是简单的表达式,还可能包含多条语句。例如,在一个嵌入式系统项目中,我们需要对硬件寄存器进行一系列操作。
2025-01-09 09:06:27
316
原创 学习记录:C++基类构造函数的调用:理解和实践
在 C++ 中,当一个类继承自基类时,基类的构造函数通常会在派生类的构造函数执行之前被调用。根据 C++ 的构造函数调用规则,如果基类有默认构造函数,编译器会在派生类构造函数体执行前自动调用基类的默认构造函数;但如果基类没有默认构造函数,那么派生类构造函数的初始化列表中必须显式调用基类的构造函数。让我们更深入地探讨这个话题。
2025-01-08 09:52:07
1036
原创 学习记录:C++初始化列表使用
使用初始化列表在 C++ 中有很多好处,尤其是在性能和语义上。它能够提高效率,减少不必要的默认构造与赋值操作;同时,它是初始化常量、引用成员以及基类成员的唯一方式;并且它还能保证成员变量按照声明的顺序进行初始化。通过合理使用初始化列表,能够编写出更高效、更安全、更可维护的代码。
2025-01-08 09:23:58
521
原创 学习记录: C++ 多线程同步机制
的构造函数在对象创建时加锁,而析构函数则在对象销毁时自动解锁。这样,我们可以避免忘记解锁或者在异常发生时未能释放锁的风险,从而减少了死锁和资源泄漏的可能。对象,并在对象的生命周期结束时释放锁。这个机制使得加锁和解锁的过程自动化,避免了手动加锁、解锁时可能引发的错误。在多线程编程中,资源竞争和数据竞争是常见的问题。是 C++ 提供的基础同步原语之一,用来保证在同一时刻只有一个线程可以访问某个共享资源。提供了自动化的加锁和解锁机制,但如果手动管理锁,容易出现一些问题,如死锁或忘记解锁。,一个自动管理锁的类。
2024-12-30 16:17:20
437
原创 学习记录:C++使用宏替换和重载函数增强函数行为
LOG我们定义一个宏LOG,它会自动将当前的文件名(__FILE__)和行号(__LINE__)作为信息传递给logMessage函数。这样,每次调用LOG宏时,不仅传递日志信息,还会传递文件名和行号。
2024-12-10 13:36:14
563
原创 学习记录:C++静态成员变量与 extern 的内存分配
静态成员变量的声明:仅在类内部声明静态成员变量时,它只是告诉编译器该成员存在,并没有分配内存。内存分配发生在类外定义时。extern声明:仅告诉编译器该变量在其他地方定义,并没有为变量分配内存。真正的内存分配发生在其他源文件中对变量的定义处。因此,在头文件中声明静态成员变量和使用extern声明变量时,都只是告诉编译器变量的存在,并不会为其分配实际的存储空间。内存分配只有在变量的定义处发生。
2024-12-10 10:19:14
498
原创 通过位运算快速地进行一些常见的数学运算
左移(<<和右移(>>可以高效地模拟乘法和除法,尤其是对于2的幂次方的操作。位运算不仅能加速常见的数学操作,还能减少计算量,适用于性能要求较高的应用场景,如嵌入式开发、图像处理、网络协议等。加上除数 - 1和右移的结合方法,能够帮助实现向上取整的操作,特别适用于需要分配字节数、内存对齐等场景。通过位运算,许多数学运算可以更高效地执行,尤其在需要处理大量数据时,这种优化能够显著提高程序的性能。
2024-12-05 11:04:50
423
原创 C#几种方式来实现将函数作为参数传递的功能
所以在 C# 中,如果不借助委托、匿名方法或者 Lambda 表达式这些机制(它们从功能实现角度来说等同于其他语言中传递函数的做法),很难实现将一段可灵活替换的逻辑(类似函数功能)作为参数传递给其他函数的操作,因为 C# 本身是依靠这些特性来达成这一灵活编程目的的。委托,其规定了对应的方法要接收两个整数参数并返回一个整数。函数时,直接通过匿名方法创建委托实例,而不需要事先单独定义具名的。方法,增加了代码书写的灵活性,尤其是对于一些简单、临时的逻辑。委托类型的参数,通过传入不同的符合委托要求的方法(也就是。
2024-11-29 14:03:54
721
原创 MFC 分段记录时间log类
在开发大型自动化系统或者多线程应用时,日志记录和时间追踪通常是系统调试和性能优化的关键部分。CAuxiliary类是一个封装了文件日志记录和高精度计时功能的实用工具类,旨在为开发人员提供一种简便的方式,来实现系统运行的日志记录和时间性能分析。本文将详细介绍如何使用CAuxiliary类来记录日志和进行高精度的时间测量。头文件源文件。
2024-11-28 11:30:09
612
原创 C++静态库的创建和使用
1.将生成的.Lib(LibTest.lib)文件和.h(LibTest.h)头文件拷贝到项目工程目录下。新建空项目,编写.h(LibTest.h)和.cpp(LibTest.cpp)文件,如下图。右键项目-》属性-》配置属性-》链接器-》输入-》附件依赖项-》添加LibTest.Lib。右键项目-》属性-》配置属性-》常规-》配置类型-》静态库(.Lib)3.添加头文件 #include“LibTest.h”MFCLibtest.cpp文件。MFCLibtest.h文件。
2024-11-20 16:10:10
313
原创 MFC线程-通过CWinThread派生类实现
Run()(可选):线程执行的核心逻辑,在这里处理线程的实际任务(例如循环计算、后台任务等)。InitInstance():线程初始化方法,执行线程启动时的资源分配和初始化操作。ExitInstance():线程结束时的清理方法,负责释放线程创建时分配的资源。:线程完成任务后,接收到的消息中包含计算结果。主线程显示这个结果,并手动清理线程对象。:通过点击按钮启动线程,并将主窗口句柄传递给线程对象,以便线程能通过消息通知主线程。线程完成任务后,主线程需要接收并处理消息。在主线程的消息映射中,注册并处理。
2024-11-20 13:48:48
548
原创 MFC线程-AfxBeginThread使用方法
一 、AfxBeginThread是 MFC(Microsoft Foundation Classes,微软基础类库)中用于创建一个新线程的函数。它返回一个指向CWinThread类对象的指针,通过这个指针可以对创建出来的线程进行后续的操作和控制。
2024-11-19 10:35:27
1290
1
原创 GIT 使用教程
通过采用合适的 Git 分支管理策略,可以帮助团队更好地组织和管理代码,提高团队的协作能力和生产效率。除了上述常见的分支管理策略,还可以根据团队的具体需求和工作流程定制适合自己的分支管理策略。总之,虽然 SVN 和 Git 都是版本控制系统,但它们的设计和实现方式存在较大差异,开发人员应根据自身需求选择最适合的版本控制系统。当两个分支上的代码修改了同一部分,并且尝试将这两个分支合并时,就会发生代码冲突。•该分支以 main 分支为基线,修复 bug 后,合并到 main 分支部。它是由 Linux 之父。
2024-11-17 17:30:40
698
原创 C++ vector的详细用法和底层原理
vector是STL容器中的一种常用的容器,和数组类似,由于其大小(size)可变,常用于数组大小不可知的情况下来替代数组。vector是为了实现动态数组而产生的容器,然而向量这个名字是STL编写者取名没区好,因为在数学上的向量在几何中是矢量,两者名字相同而意义大相径庭。vector也是一种顺序容器,在内存中连续排列,因此可以通过下标快速访问,时间复杂度为O(1)。然而,连续排列也意味着大小固定,数据超过vector的预定值时vector将自动扩容。//定义一个空的二维vector。
2024-10-25 14:08:41
1291
原创 C++中指针类型、引用类型、值类型
可能会导致程序崩溃或其他不可预期的结果。改进方案1:可以在堆上创建对象,并返回对象的指针。但这需要调用者在适当的时候手动释放内存。
2024-10-24 10:01:59
876
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人