1.原理
1.1设计窗口
wc.cbClsExtra = 0; //类的额外内存
wc.cbWndExtra = 0; //窗口额外内存
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置背景 - 白色
wc.hCursor = LoadCursor(NULL, IDC_HAND); // 设置光标,如果第一个参数为NULL , 代表使用系统提供的光标
wc.hIcon = LoadIcon(NULL, IDI_ERROR); //图标 如果第一个参数为NULL 代表使用系统提供的图标
wc.hInstance = hInstance; // 应用程序实例句柄, 传入WinMain 中的形参即可
//wc.IpfnWndProc = WindowProc; //回调函数 窗口过程
wc.lpszClassName = TEXT("WIN"); // 指定窗口类名称
wc.lpszMenuName = NULL; //菜单名称
wc.style = 0;//显示风格 0代表默认风格
1.2 注册窗口类
RegisterClass(&wc);
1.3创建窗口
HWND hwnd = CreateWindow(
wc.lpszClassName, //类名
TEXT("WINDOWS"), //标题名
WS_OVERLAPPEDWINDOW, //风格
CW_USEDEFAULT, // x坐标 默认
CW_USEDEFAULT, // y坐标 默认
CW_USEDEFAULT, // 宽 默认
CW_USEDEFAULT, // 高 默认
NULL, //父窗口
NULL, // hMeanu 菜单
hInstance, // 实例句柄 hInstance
NULL //附加值
);
1.4显示和更新
ShowWindow(hwnd, SW_SHOWNORMAL); //显示
UpdateWindow(hwnd); //更新
1.5通过循环获取消息
MSG msg;
while (true) {
// 消息
//第二个参数为NULL, 表示处理所有窗口的消息
// 最小和最大的过滤的消息 , 填入0
// 填0代表捕获所有消息
if (GetMessage(&msg, NULL, 0, 0) == FALSE) {
break;
}
//翻译消息
TranslateMessage(&msg);
//不为false
//分发消息
DispatchMessage(&msg);
}
1.6处理窗口过程
//6. 处理消息(窗口过程) 使用回调函数
LRESULT CALLBACK WindowProc(
HWND hwnd, // 消息所属的窗口句柄
UINT uMsg, //具体消息名称 WM_XXX消息名
WPARAM wParam, // 键盘附加消息
LPARAM lParam //鼠标附加消息
)
{
switch (uMsg) {
case WM_CLOSE:
DestroyWindow(hwnd); // 发送另一个消息 WM_DESTROY
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN: // 鼠标左键按下
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
wchar_t buf[1024];
wsprintf(buf,TEXT("x = %d , y = %d"), xPos, yPos);
MessageBox(hwnd,TEXT("aaa"),TEXT("鼠标左键按下"),MB_OK);
break;
case WM_KEYDOWN: //键盘
MessageBox(hwnd, TEXT("键盘按下"), TEXT("键盘按下"), MB_OK);
break;
case WM_PAINT: //绘图
PAINTSTRUCT ps;// 绘图结构体
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 100, 100, TEXT("HELLO", strlen("HELLO")));
EndPaint(hwnd,&ps);
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
//返回值用默认处理方式
}
1.7完整代码
#include<Windows.h>
//6. 处理消息(窗口过程) 使用回调函数
LRESULT CALLBACK WindowProc(
HWND hwnd, // 消息所属的窗口句柄
UINT uMsg, //具体消息名称 WM_XXX消息名
WPARAM wParam, // 键盘附加消息
LPARAM lParam //鼠标附加消息
)
{
switch (uMsg)
{
case WM_CLOSE:
DestroyWindow(hwnd); // 发送另一个消息 WM_DESTROY
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_LBUTTONDOWN: // 鼠标左键按下
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
wchar_t buf[1024];
wsprintf(buf, TEXT("x = %d , y = %d"), xPos, yPos);
MessageBox(hwnd, TEXT("aaa"), TEXT("鼠标左键按下"), MB_OK);
break;
}
case WM_KEYDOWN: //键盘
MessageBox(hwnd, TEXT("键盘按下"), TEXT("键盘按下"), MB_OK);
break;
case WM_PAINT: //绘图
{
PAINTSTRUCT ps;// 绘图结构体
HDC hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 100, 100, TEXT("HELLO"), strlen("HELLO"));
EndPaint(hwnd, &ps);
}
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
//返回值用默认处理方式
}
int WINAPI WinMain(
HINSTANCE hInstance, // 应用程序实例句柄
HINSTANCE hPrevInstance, //上一个应用程序句柄 在Win32环境下 一般为NULL 不起作用了
LPSTR lpCmdLine,
int nShowCmd // 显示命令 最大化 最小化 正常
)
{
//1. 设计窗口
WNDCLASS wc;
wc.cbClsExtra = 0; //类的额外内存
wc.cbWndExtra = 0; //窗口额外内存
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置背景 - 白色
wc.hCursor = LoadCursor(NULL, IDC_HAND); // 设置光标,如果第一个参数为NULL , 代表使用系统提供的光标
wc.hIcon = LoadIcon(NULL, IDI_ERROR); //图标 如果第一个参数为NULL 代表使用系统提供的图标
wc.hInstance = hInstance; // 应用程序实例句柄, 传入WinMain 中的形参即可
wc.lpfnWndProc = WindowProc; //回调函数 窗口过程
wc.lpszClassName = TEXT("WIN"); // 指定窗口类名称
wc.lpszMenuName = NULL; //菜单名称
wc.style = 0;//显示风格 0代表默认风格
//2. 注册窗口
RegisterClass(&wc);
//3. 创建窗口
HWND hwnd = CreateWindow(
wc.lpszClassName, //类名
TEXT("WINDOWS"), //标题名
WS_OVERLAPPEDWINDOW, //风格
CW_USEDEFAULT, // x坐标 默认
CW_USEDEFAULT, // y坐标 默认
CW_USEDEFAULT, // 宽 默认
CW_USEDEFAULT, // 高 默认
NULL, //父窗口
NULL, // hMeanu 菜单
hInstance, // 实例句柄 hInstance
NULL //附加值
);
//4. 显示和更新
ShowWindow(hwnd, SW_SHOWNORMAL); //显示
UpdateWindow(hwnd); //更新
//5. 通过循环取消息
MSG msg;
while (1) {
// 消息
//第二个参数为NULL, 表示处理所有窗口的消息
// 最小和最大的过滤的消息 , 填入0
// 填0代表捕获所有消息
if (GetMessage(&msg, NULL, 0, 0) == FALSE) {
break;
}
//翻译消息
TranslateMessage(&msg);
//不为false
//分发消息
DispatchMessage(&msg);
}
return 0;
}
2.MFC
2.1 包含头文件
2.2 简单的一个MFC应用
2.2.1 代码简略
2.2.2 在vs中设置使用共享DLL的MFC
2.2.3 头文件代码
#include<afxwin.h>
class MyApp:public CWinApp //CWinApp应用程序类
{
public:
//基类的虚函数 派生类只是重写
//程序入口
virtual BOOL InitInstance();
};
//框架类 CFrameWnd 子类
class MyFrame:public CFrameWnd //窗口框架类
{
public:
MyFrame();
};
2.2.4 cpp文件代码
#include"mfc.h"
MyApp app;//有且只有一个全局的应用程序窗口类对象
BOOL MyApp::InitInstance()
{
//1.创建框架类对象 创建窗口
MyFrame* frame = new MyFrame;
//显示和更新
frame->ShowWindow(SW_SHOWNORMAL); // 显示窗口
frame->UpdateWindow(); //更新窗口
m_pMainWnd = frame; //保存指向应用程序的主窗口的指针
return TRUE;
}
MyFrame::MyFrame()
{
Create(NULL, TEXT("mfc"));
}
2.3 消息映射
2.3.1 简介
2.3.2 简略代码
2.3.3消息映射宏
2.3.4示例代码头文件
#include<afxwin.h>
class MyApp:public CWinApp //CWinApp应用程序类
{
public:
//基类的虚函数 派生类只是重写
//程序入口
virtual BOOL InitInstance();
};
//框架类 CFrameWnd 子类
class MyFrame:public CFrameWnd //窗口框架类
{
public:
MyFrame();
//声明宏 提供消息映射机制
DECLARE_MESSAGE_MAP()
afx_msg void OnLButtonDown(UINT, CPoint);
afx_msg void OnChar(UINT, UINT, UINT);
afx_msg void OnPaint();
};
2.3.5示例代码cpp文件
#include"mfc.h"
MyApp app;//有且只有一个全局的应用程序窗口类对象
BOOL MyApp::InitInstance()
{
//1.创建框架类对象 创建窗口
MyFrame* frame = new MyFrame;
//显示和更新
frame->ShowWindow(SW_SHOWNORMAL); // 显示窗口
frame->UpdateWindow(); //更新窗口
m_pMainWnd = frame; //保存指向应用程序的主窗口的指针
return TRUE;
}
//分界宏
BEGIN_MESSAGE_MAP(MyFrame, CFrameWnd)
ON_WM_LBUTTONDOWN() //鼠标左键按下
ON_WM_CHAR() //键盘
ON_WM_PAINT()//绘图宏
END_MESSAGE_MAP()
MyFrame::MyFrame()
{
Create(NULL, TEXT("mfc"));
}
void MyFrame::OnLButtonDown(UINT, CPoint point)
{
//mfc里的字符数组
TCHAR buf[1024];
//wsprintf(buf, TEXT("x = %d, y = %d"), point.x, point.y);
////对话框
//MessageBox(buf);
//mfc 中的字符串 CString
CString str;
str.Format(TEXT("x = %d,,, y = %d"), point.x, point.y);
MessageBox(str);
}
void MyFrame::OnChar(UINT key, UINT, UINT)
{
CString str;
str.Format(TEXT("按下了 %c 键"), (char)key);
MessageBox(str);
}
void MyFrame::OnPaint()
{
CPaintDC dc(this); //指定绘图的设备
dc.TextOutW(100, 100, TEXT("为了部落"));
//画椭圆
dc.Ellipse(10, 10, 100, 100);
}
2.4 字符编码
2.4.1 统计宽字节的字符串长度
2.4.2 char*与CString之间的转换
2.5 利用向导创建MFC
通过vs创建
2.6 使用
选择所需要的窗口事件 , 右键添加
如果有了OnDraw 再有OnPaint 会覆盖掉
- MFC中后缀名为Ex的函数都是扩展函数
- MFC中以Afx为前缀的函数都是全局函数 , 可以在程序的任何地方调用他们
view 视类 相片 MainFram类 相框
OnCreate相应创建窗口-设置风格属性等 Create创建窗口 WM_CREATE 消息是由Create函数调用的 一个窗口(Create)后会向系统发送WM_CREATE消息,OnCreate响应此消息
2.7 基于对话框进行操作
2.7.1 查找主窗口路径
2.7.2 模态对话框
创建类 , 去创建一个和该按钮对应的类
三种添加事件的方法
右键属性 - 控件事件
右键 - 添加事件处理程序
双击该按钮
在头文件引入刚才创建的那个对话框的类的头文件
//弹出模态对话框
CDlgExec dlg;
dlg.DoModal();
2.7.3 非模态对话框
-
创建视图对应类
-
添加触发事件
-
导入头文件
-
写弹出的方法
void CMFCApplication2Dlg::OnBnClickedButton2() { // TODO: 在此添加控件通知处理程序代码 //弹出非模态对话框 CDlgShow dlg; //创建 dlg.Create(IDD_DIALOG2);//创建一个窗口只能创建一次 , 多次会崩 //显示 dlg.ShowWindow(SW_SHOWNORMAL); }
因为生存周期的问题 , 方法执行完这个窗口类会释放, 所以需要在大对话框的头文件中去申明他
同时 大的对话框的头文件中, 需要引入这个非模态对话框的头文件
而且这只能创建一次 , 再创建一次会崩溃
所以需要放到初始化函数里,防止二次执行创建操作
找到初始化方法
后面其他UI组件的用法其实大差不差直接看着文档写或者就看着demo代码来写就行了,懒得记录了,有一说一 , 这玩意是真的辣鸡
标签:MFC,窗口,随笔,TEXT,WM,学习,hwnd,wc,NULL From: https://www.cnblogs.com/jy00/p/17374605.html