Accerlerators
一般是在OnCreate
的时候::LoadAccelerators
, MFC 会在LoadFrame
顺带做了::LoadAccelerators
的操作
Keyboard Message
而WM_SYSKEYDOWN是接受快捷键或系统命令按键的,像Alt键就是。所以捕获Alt键时,在WM_KEYDOWN下是无效的,要在WM_SYSKEYDOWN中。Ctrl和shift不属于WM_SYSKEYDOWN。
Tab cycle
想要一个内嵌式的dialog加入到tab cycle, 需要设置样式DS_CONTROL
WM_CTLCOLORLISTBOX
当listbox内容为空的时候会通过父窗口这个消息控制默认背景色。
关于Auto Cleanup Classes
https://docs.microsoft.com/en-us/cpp/mfc/tn017-destroying-window-objects?view=vs-2019
MFC中的基本规则是:
MFC控件都不是Auto Cleanup Classes, 所以基本都是在栈上创建的。
Auto Cleanup Classes必须在堆上创建,因为他们的PostNcDestroy中都会delete this,如果不是堆上创建的会出错。
总结
1.可以有两种方法销毁窗口对象对应的窗口和释放窗口对象指针。一种是通过DestroyWindow
。这是比较好的方法,因为最后MFC会自动相应WM_CLOSE
导致CframWnd::DestroyWindow
被调用,然后会一次释放所有子窗口的句柄。用户需要做的是在PostNcDestroy
中释放堆窗口对象指针。但因为某些对象是在栈中申请的,所以delete this可能出错。这就要保证写程序时自己创建的窗口尽量使用堆申请。
2.另一种是delete
。Delete一个窗口对象指针有的窗口类(如CWnd
,Cdialog
)会间接调用DestroyWindow
,有的窗口类(如CView
,CframeWnd
)不会调用DestroyWindow
。所以要小心应对。
If you want to break these rules, you must override the
PostNcDestroy
method in your derived class.To add auto-cleanup to your class, call your base class and then do a delete this. To remove auto-cleanup from your class, callCWnd::PostNcDestroy
directly instead of thePostNcDestroy
method of your direct base class.
通常来说,mfc的控件、对话框的删除,如果是在栈上创建的,那么不需要显示调用DestoryWindow,因为它们的基类析构函数会做这件事。如果它们是在堆上创建,那么简单地delete就好了。对于Auto Cleanup Classes直接调用DestroyWindow
来删除,不需要再手动delete一遍。
给CWnd发送WM_CLOSE相当于调用DestroyWindow
。
https://www.cnblogs.com/endenvor/p/9796687.html
WAV 格式
https://www.cnblogs.com/ranson7zop/p/7657874.html
通过IAudioClient GetMixFormat 的 format tag如果是WAVE_FORMAT_EXTENSIBLE (0x00FE),那么格式将由subformat(GUID)来指定,cbsize指定了
WAVEFORMATEX之后至少多少个字节长度.
typedef struct {
WAVEFORMATEX Format;
union {
WORD wValidBitsPerSample;
WORD wSamplesPerBlock;
WORD wReserved;
} Samples;
DWORD dwChannelMask;
GUID SubFormat;
} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE;
RF-64 WAV
rf64_graph.pngEVENT
初始状态在
bInitialState
参数中进行设置。使用SetEvent
函数将事件对象的状态置为有信号状态。使用ResetEvent
函数将事件对象的状态置为无信号状态。
当一个手动复原的事件对象的状态被置为有信号状态时,该对象状态将一直保持有信号状态,直至明确调用
ResetEvent
函数将其置为无符号状态。当事件的对象被置为有信号状态时,任意数量的等待中线程,以及随后开始等待的线程均会被释放。
当一个自动复原的事件对象的状态被置为有信号状态时,该对象状态将一直保持有信号状态,直至一个等待线程被释放;系统将自动将此函数置为无符号状态。如果没有等待线程正在等待,事件对象的状态将保持有信号状态
这段话的意思是,比如一堆线程在等待一个event,当event被SetEvent
设置为有信号状态,如果event是自动复原的,那么只会有一个等待线程被释放,并且event对象会复原到无信号状态;如果事件是手动复原的,那么所有等待线程都会被释放,event会一直保持有信号状态,直到显式调用ResetEvent
。
ResetEvent
function
Sets the specified event object to the nonsignaled state.
Windows C++程序入口点
实际入口是由C运行时库的这几个函数
1. mainCRTStartup(或 wmainCRTStartup) //使用 /SUBSYSTEM:CONSOLE 的应用程序
2. WinMainCRTStartup(或 wWinMainCRTStartup) //使用 /SUBSYSTEM:WINDOWS 的应用程序
3. _DllMainCRTStartup //调用 DllMain(如果存在),DllMain 必须用 __stdcall 来定义
Linker 负责链接其中一种C Runtime startup code到exe中(根据子系统和是否定义了main
或 WinMain
)
lambda捕获列表
-
空
没有使用任何函数对象参数。 -
=
函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。 -
&
函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this),并且是引用传递方式(相当于编译器自动为我们按引用传递了所有局部变量)。 -
this
函数体内可以使用Lambda所在类中的成员变量。 -
a
将a按值进行传递。按值进行传递时,函数体内不能修改传递进来的a的拷贝,因为默认情况下函数是const的。要修改传递进来的a的拷贝,可以添加mutable修饰符。 -
&a
将a按引用进行传递。 -
a
,&b
将a按值进行传递,b按引用进行传递。 -
=
,&a
,&b
除a和b按引用进行传递外,其他参数都按值进行传递。 -
&
,a
,b
除a和b按值进行传递外,其他参数都按引用进行传递。
网友评论