随笔- 62  文章- 1  评论- 5  阅读- 13061 

1.原理

image-20221111113204739

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通过循环获取消息

image-20221111120936349

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 包含头文件

image-20221111145416054

2.2 简单的一个MFC应用

2.2.1 代码简略

image-20221111145503518

2.2.2 在vs中设置使用共享DLL的MFC

image-20221111150534795

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 简介

image-20221111163933863

2.3.2 简略代码

image-20221111163950556

2.3.3消息映射宏

image-20221111164214133

image-20221111164336139

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 统计宽字节的字符串长度

image-20221111210736538

2.4.2 char*与CString之间的转换

image-20221111210817688

2.5 利用向导创建MFC

通过vs创建

image-20221111211808891

2.6 使用

image-20221111212533105

image-20221111212545641

选择所需要的窗口事件 , 右键添加

image-20221111212518698

如果有了OnDraw 再有OnPaint 会覆盖掉

  • MFC中后缀名为Ex的函数都是扩展函数
  • MFC中以Afx为前缀的函数都是全局函数 , 可以在程序的任何地方调用他们

view 视类 相片 MainFram类 相框

OnCreate相应创建窗口-设置风格属性等 Create创建窗口 WM_CREATE 消息是由Create函数调用的 一个窗口(Create)后会向系统发送WM_CREATE消息,OnCreate响应此消息

2.7 基于对话框进行操作

2.7.1 查找主窗口路径

image-20221111215234899

image-20221111215302201

2.7.2 模态对话框

image-20221113175958108

创建类 , 去创建一个和该按钮对应的类

image-20221113180607433

三种添加事件的方法

右键属性 - 控件事件

右键 - 添加事件处理程序

双击该按钮

image-20221113180839371

在头文件引入刚才创建的那个对话框的类的头文件

//弹出模态对话框
CDlgExec dlg;
dlg.DoModal();

2.7.3 非模态对话框

  • 创建视图对应类

  • 添加触发事件

  • 导入头文件

  • 写弹出的方法

    void CMFCApplication2Dlg::OnBnClickedButton2()
    {
    // TODO: 在此添加控件通知处理程序代码
    //弹出非模态对话框
    CDlgShow dlg;
    //创建
    dlg.Create(IDD_DIALOG2);//创建一个窗口只能创建一次 , 多次会崩
    //显示
    dlg.ShowWindow(SW_SHOWNORMAL);
    }

因为生存周期的问题 , 方法执行完这个窗口类会释放, 所以需要在大对话框的头文件中去申明他

image-20221113191435872

同时 大的对话框的头文件中, 需要引入这个非模态对话框的头文件

image-20221113191629290

而且这只能创建一次 , 再创建一次会崩溃

所以需要放到初始化函数里,防止二次执行创建操作

找到初始化方法

image-20221113191916677

image-20221113192032996

后面其他UI组件的用法其实大差不差直接看着文档写或者就看着demo代码来写就行了,懒得记录了,有一说一 , 这玩意是真的辣鸡

 posted on     阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示

目录导航