为什么std::tolower不能用于std::transform
在C++中,std::tolower和std::toupper函数(在本文中都用std::tolower指代两者)用于对一个字符进行大小写转换,将其与std::transform函数结合则可以对整个字符串进行大小写转换,如下所示:
在C++中,std::tolower和std::toupper函数(在本文中都用std::tolower指代两者)用于对一个字符进行大小写转换,将其与std::transform函数结合则可以对整个字符串进行大小写转换,如下所示:
本文在《创建一个最简单的Windowless RichEdit》一文的基础上,介绍如何让Windowless RichEdit支持编辑功能。
RAND_poll函数是OpenSSL中用于初始化伪随机数生成器的函数,当首次调用诸如RAND_bytes等需要生成随机数的函数时,会先调用该函数进行初始化。在实际使用中发现,RAND_poll函数在Windows下存在一些问题,需要小心提放,否则可能会对程序造成不良影响。
RichEdit是Windows上很常用的富文本控件,它有一个无窗口化的版本,即Windowless RichEdit,关于它的介绍,可以参考官方文档:https://msdn.microsoft.com/en-us/library/windows/desktop/bb787609(v=vs.85).aspx 。Windowless RichEdit与普通RichEdit在行为表现上毫无二致,但是在使用方法上却有较大的差异;而且Windowless RichEdit的官方文档少之又少,说明不够全面,甚至连一个完整的示例也没有;更甚者,在不同的Windows平台和开发环境下,Windowless RichEdit的用法都有差异。这让初次接触Windowless RichEdit的人举步维艰,处处碰壁,正应了“万事开头难”这句话。因此,本文聚焦于“开头”,介绍一下创建一个最简单的Windowless RichEdit需要做哪些事情。
在Windows界面开发中,启动定时器的最常用方法是使用SetTimer这个API。通过这个API启动的定时器会持续不断地往窗口消息队列中投递WM_TIMER消息,直到调用了KillTimer来停止。一个有趣的问题是,假如定时器的消息程序处理不过来,即处理WM_TIMER的时间比定时器的间隔时间长,会发生什么事情呢?消息队列中是否会堆积越来越多的WM_TIMER消息?官方文档中并没有指出这个问题,只能通过实践来找出答案。
C++11新增的智能指针std::shared_ptr使用引用计数来管理对象的生命周期,而COM提供的IUnknown接口也使用引用计数来管理自身的生命周期。理论上来说,在同一个环境中不应该同时使用两套引用计数方案,不然会造成混乱,带来很多麻烦。然而实际上,需要同时使用这两种方案的情况并不少见,有时的确需要用std::shared_ptr来持有COM对象。虽然这种做法看上去丑陋,并且是可以用别的方法来避免的,但本文不讨论这些方面,只聚焦于问题的本身。
C++11标准库新增的std::thread类可以方便地开启子线程。然而有个奇怪的现象是,如果在这些子线程中抛出了未处理的C++异常而导致程序崩溃,那么在生成的dump文件中将还原不出异常发生时的调用栈。可以通过下面的方法来展示这个现象。
日志是一种有效的调试手段。但是日志写得太频繁会降低程序性能,所以一般采取的策略是,大部分日志只在调试版的程序中输出,少量重要的日志才在发行版的程序中输出。为了控制调试日志的输出,通常会使用下面的简便方法: