UI
MFC
程序启动流程
- 系统
shell加载程序的code、data、dll并调用CreateProcess()创建了一个代表你程序的进程 - 启动第一个线程(
PCB,TCB等的创建)
MFC程序启动流程
_tWinMain–>AfxWinMain(WINMAIN.CPP 21)AfxWinMain()负责调用CWinApp中的InitApplication(),InitInstance(),Run()等几个主要函数.
WinMain
int WINAPI WinMain(HINSTANCE hInstance/*当前进程句柄*/, HINSTANCE hPrevInstance/*win32:NULL*/, LPSTR cmd/*argv*/, int show/*maxmize...*/) {
WNDCLASS wc = {0};
wc.lpszClassName = "ZClass";
wc.lpfnWndProc = (WNDPROC)ZWindowProc;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.style = CS_VERDRAW | CS_HREDRAW | CS_NOCLOSE/*禁止标题栏关闭*/;
if (!RegisterClass(&wc)) { return 0; }
// CreateWindow会产生WM_CREATE消息,这是窗口过程收到的第1个消息.
HWND hWndMain = CreateWindow("ZClass", "caption", WS_OVERLAPPEDWINDOW, 0,0,8,8, NULL,NULL, hInstance, NULL);
ShowWindow(hWndMain, SW_SHOW);
// emit WM_PAINT, 这是窗口过程的第2个消息!
UpdateWindow(hWndMain);
/* 消息循环 */
MSG msg;
while (GetMessage(&msg, NULL, 0,0)) { // NULL:获取所有窗口消息;2个0:不过滤
// 将WM_KEYDOWN翻译成WM_CHAR.
TranslateMessage(&msg);
// 将消息转发(OS)到窗口过程!
DispatchMessage(&msg);
}
return 0;
}
Message Map
CObject实现了运行时类型识别功能:CObject::IsKindOf()CCmdTarget实现了消息映射CWinThread没有保存消息映射表,故不适用其父类:BEGIN_MESSAGE_MAP(CWinApp, CCmdTarget)declare_message_map这些宏主要是为了使当前消息映射节点加入到消息映射的链表中去.AFX_MSGMAP的类都保存了一张表,记录了"消息-处理函数"之间的对应关系
消息的种类
- 命令消息:
WM_COMAMDN,CCmdTarget; UI对象、菜单、工具栏、按钮 - 控件消息:
WM_NOTIFY,也属于命令消息的一种,是控件发送给父窗口的"通知消息"; - 标准消息:
WM_PAINT,WM_CREATE,WM_CHAR,WM_LBUTTONDOWN..除了上面两种之外的消息.CWnd不需要我们指定函数名!
AFX_MSGMAP
enum AfxSig { // 消息映射响应函数参数及返回值的类型
AfxSig_end = 0, // [marks end of message map]
AfxSig_bD, // BOOL (CDC*)
AfxSig_bb, // BOOL (BOOL)...
};
typedef void (CCmdTarget::*AFX_PMSG)(void); // CCmdTarget类的void-void成员函数指针类型
struct AFX_MSGMAP_ENTRY { // 记录(控件上的)消息所对应的"消息处理函数"----消息映射的节点
UINT nMessage; // WM_CREATE、WM_COMMAND、WM_MOVE、WM_SIZE、WM_PAINT...
UINT nCode; // 控件消息的控制码,如: BN_CLICKED、
UINT nID; // 控件ID:IDC_BUTTON1.., 0:标准消息
UINT nLastID; // 指定一定范围内的消息被映射,或两者一样
UINT nSig; // pfn函数类型.见上方AfxSig的定义
AFX_PMSG pfn; // 是一个指向CCmdTarget类非静态成员函数指针
};
struct AFX_MSGMAP { // 消息映射链表,便于从年轻的消息映射节点走访到最老的消息映射节点.
const AFX_MSGMAP* pBaseMap; // 记录基类的(baseClass)messageMap成员以便向上走访,基类消息映射表使子类可以走访到基类,类似于虚函数
const AFX_MSGMAP_ENTRY* lpEntries; // _messageEntries[]成员的地址
};
DECLARE_MESSAGE_MAP
下面都定义了_AFXDLL版本(动态连接到MFC-dll)
Dart 3
Migration Guide
新特性
var (String name, _) = userInfo({});
const record = (a: 1, b: true);
print('${record.a} ${record.b}');

