Windows窗口
Windows窗口
Unit01注册窗口类
01窗口类的概念
窗口类是
包括了窗口的各种参数信息的数据结构
- 每个窗口都具有窗口类,基于窗口类创建窗口
- 每个窗口都具有一个名称,使用前必须注册到系统
02窗口类的分类
- 系统窗口类
系统已经定义好的窗口类,所有应用程序都可以直接使用 - 应用程序全局窗口类
由用户自己定义,当前应用程序所有模块都可以使用 - 应用程序局部窗口类
由用户自己定义,当前应用程序中本模块可以使用
03系统窗口
-
不需要注册,直接使用窗口类即可。系统已经注册好了
例如:- 按钮:BUTTON
- 编辑框:EDIT
-
示例:创建一个巨大的按钮
#include <windows.h>//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//在内存创建窗口HWND hWnd = CreateWindow("Button","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理}return 0;
}
04全局及局部窗口类
- 注册窗口类的函数
ATON RegisterClass(CONST WNDCLASS *lpWndClass//窗口类的数据
);//注册成功后,返回一个数字标识(返回0注册失败,非0注册成功)
- 注册窗口类的结构体
typedef struct _WNDCLASS{UINT style;//窗口类的风格WNDPROC lpfnWndProc;//窗口处理函数int cbClsExtra;//窗口类的附加数据buff的大小int cbWndExtra;//窗口的附加数据buff的大小HINSTANCE hInstance;//当前模块的实例句柄HICON hIcon;//窗口图标句柄HCURSOR hCursor,//鼠标的句柄HBRUSH hbrBackground,//绘制窗口背景的画刷句柄LPCTSTR lpszMenuName,//窗口菜单的资源ID字符串LPCTSTR lpszClassName//窗口类的名称
}WNDCLASS,*PWNDCLASS;
- style窗口类风格
- 应用程序全局窗口类的注册,需要在窗口类的风格中增加
CS_GLOBALCLASS
例如:
WNDCLASS wce = {0}; wce.style = ...|CS_GLOBALCLASS;
- 应用程序局部窗口类:在注册窗口类时,不添加
CS_GLOBALCLASS
风格 - 其他窗口类风格:
- CS_HREDREAW:当窗口水平发生变化时,窗口重新绘制
- CS_VREDREAW:当窗口垂直发生变化时,窗口重新绘制
- CS_DBLCLKS:允许窗口接收鼠标双击
- CS_NOCLOSE:窗口没有关闭按钮
- 应用程序全局窗口类的注册,需要在窗口类的风格中增加
Unit02窗口创建
01窗口创建
- CreateWindow/CreateWindowEx
HWND CreateWindowEx{DWORD dwExStyle,//窗口的扩建风格LPCTSTR lpClassName,//已经注册的窗口类名称LPCTSTR lpWindowName,//窗口标题栏的名字DWORD dwStyle,//窗口的基本风格int x,//窗口左上角水平坐标位置int y,//窗口左上角的垂直坐标位置int nWidth,//窗口的宽度int nHeight,//窗口的高度HWND hWndParent,//窗口的父窗口句柄HMENU hMenu,//窗口菜单句柄HINSTANCE hInstance,//应用程序实例句柄LPVOID lpParam//窗口创建时俯角参数
};//创建成功返回窗口句柄
#include <windows.h>//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{return DefWindowProc(hWnd, msgID, wParam, lParam);
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//注册窗口类WNDCLASS wc = {0};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Main";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口HWND hWnd = CreateWindowEx(0,"Main","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理}return 0;
}
02窗口创建执行过程
- 1.系统(CreateWindowEx函数内部)根据传入的窗口类名称,在因用程序局部窗口类中查找,如果找到执行第2步,否则执行第3步
- 2.比较局部窗口类与创建时传入的HINSTANCE变量。如果发现相等,创建和注册的窗口类在同一模块,创建窗口返回。如果不相等,继续执行第3步
- 3.在应用程序全局窗口类,如果找到执行第4步,否则执行第5步
- 4.使用找到的窗口类的信息,创建窗口返回
- 5.在系统窗口类中查找,如果找到创建窗口返回,否则创建窗口失败
解决遗留问题:点击窗口的关闭按钮可以完全退出进程,不用在任务管理器中杀死进程
#include <windows.h>//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;}return DefWindowProc(hWnd, msgID, wParam, lParam);
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//注册窗口类WNDCLASS wc = {0};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Main";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口HWND hWnd = CreateWindowEx(0,"Main","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理}return 0;
}
03 子窗口创建
- 创建时要设置父窗口句柄
- 创建风格要增加
WS_CHILD|WS_VISIBLE
#include <windows.h>//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;}return DefWindowProc(hWnd, msgID, wParam, lParam);
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//注册窗口类WNDCLASS wc = {0};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Main";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口HWND hWnd = CreateWindowEx(0,"Main","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//子窗口窗口类wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Child";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 = CreateWindowEx(0,"Child","c1",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 = CreateWindowEx(0,"Child","cc",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理}return 0;
}
Unit03消息基础
01消息的概念和作用
- 消息组成(Windows平台下的消息)
- 窗口句柄
- 消息ID
- 消息的两个参数(两个附带信息)
- 消息的产生时间
- 消息产生时的鼠标位置
- 消息的作用
- 当系统通知窗口工作时,就采用消息的方式
(DispatchMessage)
派发给窗口的窗口处理函数
- 当系统通知窗口工作时,就采用消息的方式
/** Message structure*/
typedef struct tagMSG {HWND hwnd;UINT message;WPARAM wParam;LPARAM lParam;DWORD time;POINT pt;
#ifdef _MACDWORD lPrivate;
#endif
} MSG, *PMSG, NEAR *NPMSG, FAR *LPMSG;
02窗口处理函数
- 每个窗口都必须具有窗口处理函数
LRESULT CALLBACK WindowProc(HWND hwnd,//窗口句柄UINT uMsg,//消息IDWPARAM wParam,//消息参数LPARAM lParam//消息参数
);
- 当系统通知窗口时,会调用窗口处理函数,同时将消息ID和消息参数床底给窗口处理函数。在窗口处理函数中,不处理的消息,使用缺省窗口处理函数。例如:
DefWindowProc
03 浅谈消息相关函数
GetMessage
获取本进程的消息
BOOL GetMessage(LPMSG lpMsg,//存放获取到的消息BUFF//后面三个参数都是指定抓取消息的范围HWND hWnd,//窗口句柄(如果指定为NULL,表示抓取全部窗口的消息)UINT wMsgFilterMin,//获取消息的最小IDUINT wMsgFilteMax//获取消息的最大ID
);
//lpMsg:当获取到消息后,将消息的参数存放到MSG结构中
//hWnd:获取到hWnd所指定窗口的消息
//wMsgFilterMin和wMsgFilteMax:只能获取到由它们指定的消息范围内的消息,如果都为0,表示没有范围
TranslateMessage
翻译消息,将按键消息,翻译成字符消息
检查消息是否是按键的消息,如果不是按键消息,不做任何处理,继续执行(该函数只翻译可见字符的按键消息)
BOOL TranslateMessage(const MSG* lpMsg//要翻译的消息地址
);
DispatchMessage
派发消息
将消息派发到该消息所属窗口的窗口处理函数上
LONG LONG DispatchMessage( const MSG* lpmsg //要派发的消息
);
Unit04常见消息
01WM_DESTORY
- 产生时间:窗口被销毁时的消息
- 附带信息:
- wParam:0
- lParam:0
- 一般用法:常用语在窗口销毁之前,做相应的善后处理,例如资源、内存的释放等
//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
02WM_SYSCOMMAND
- 产生时间:当点击窗口的最大化、最小化、关闭等
- 附带信息:
- wParam:具体点击的位置,例如关闭
SC_CLOSE
等 - lParam:鼠标光标的位置(使用一个long类型的高低位分别存储两个数,使用下面的两个宏定义取出两个数)
- LOWORD(lParam);//水平位置
- HIWORD(lParam);//垂直位置
- wParam:具体点击的位置,例如关闭
- 一般用法:常用在窗口关闭时,提示用户处理
#include <windows.h>//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;case WM_SYSCOMMAND:MessageBox(hWnd,"02WM_SYSCOMMAND","Info",MB_OK);break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//注册窗口类WNDCLASS wc = {0};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Main";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口HWND hWnd = CreateWindowEx(0,"Main","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//子窗口窗口类wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Child";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 = CreateWindowEx(0,"Child","c1",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 = CreateWindowEx(0,"Child","cc",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理}return 0;
}
#include <windows.h>//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;case WM_SYSCOMMAND:if(wParam == SC_CLOSE){MessageBox(hWnd,"是否退出","Info",MB_YESNO);}else{return 0;}break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//注册窗口类WNDCLASS wc = {0};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Main";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口HWND hWnd = CreateWindowEx(0,"Main","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,NULL);//子窗口窗口类wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Child";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 = CreateWindowEx(0,"Child","c1",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 = CreateWindowEx(0,"Child","cc",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理}return 0;
}
03WM_CREATE
- 产生时间:在窗口创建成功但还没显示时
- 附带信息:
- wParam:0
- lParam:为
CREATESTRUCT
类型的指针。通过这个指针获取CreateWindowEx
中的全部12个参数的信息
- 一般用法:常用于初始化窗口的参数、资源等等,包括创建子窗口等
#include <windows.h>void onCreate(HWND hWnd, LPARAM lParam){CREATESTRUCT* psc = (CREATESTRUCT*)lParam;char* pszText = (char*)psc->lpCreateParams;MessageBox(NULL, pszText,"Info",MB_OK);//创建子窗口CreateWindowEx(0,"EDIT","hello",WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,200,200,hWnd,NULL,0,NULL);
}
//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_CREATE:onCreate(hWnd, lParam);break;case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;case WM_SYSCOMMAND:if(wParam == SC_CLOSE){MessageBox(hWnd,"是否退出","Info",MB_YESNO);}else{return 0;}break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{//注册窗口类WNDCLASS wc = {0};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Main";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口char* pszText = "hello data";HWND hWnd = CreateWindowEx(0,"Main","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,pszText);//子窗口窗口类wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Child";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 = CreateWindowEx(0,"Child","c1",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 = CreateWindowEx(0,"Child","cc",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理}return 0;
}
04WM_SIZE
- 产生时间:在窗口的大小发生变化
- 附带信息:
- wParam:窗口大小变化的原因
- lParam:窗口变化后的大小
- LOWORD(lParam);//水平位置
- HIWORD(lParam);//垂直位置
- 一般用法:常用于窗口大小变化后,调整窗口内各个部分的布局
#include <windows.h>
#include <stdio.h>HANDLE g_hOutput = 0;//接收标准输出句柄
void onSize(HWND hWnd, LPARAM lParam){short nWidth = LOWORD(lParam);short nHight = HIWORD(lParam);char szText[256] = {0};sprintf(szText, "WM_SIZE:宽:%d,高:%d\n", nWidth, nHight);WriteConsole(g_hOutput, szText,strlen(szText),NULL,NULL);
}void onCreate(HWND hWnd, LPARAM lParam){CREATESTRUCT* psc = (CREATESTRUCT*)lParam;char* pszText = (char*)psc->lpCreateParams;MessageBox(NULL, pszText,"Info",MB_OK);//创建子窗口CreateWindowEx(0,"EDIT","hello",WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,200,200,hWnd,NULL,0,NULL);
}
//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_SIZE:onSize(hWnd, lParam);break;case WM_CREATE://onCreate(hWnd, lParam);break;case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;case WM_SYSCOMMAND:if(wParam == SC_CLOSE){MessageBox(hWnd,"是否退出","Info",MB_YESNO);}else{return 0;}break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{AllocConsole();//增加一个DOC窗口g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//注册窗口类WNDCLASS wc = {0};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Main";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口char* pszText = "hello data";HWND hWnd = CreateWindowEx(0,"Main","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,pszText);//子窗口窗口类wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Child";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 = CreateWindowEx(0,"Child","c1",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 = CreateWindowEx(0,"Child","cc",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理}return 0;
}
05WM_QUIT
- 产生时间:程序员发送
- 附带信息:
- wParam:PostQuitMessage函数传递参数
- lParam:0
- 一般用法:用于结束消息循环,当GetMessage收到这个消息后,会返回FALSE,结束while处理,退出消息循环
Unit05消息循环的原理
01消息循环的阻塞
GetMessage
从系统获取消息,将消息从系统中移除,是一个阻塞函数。当系统无消息时,会一直等待下一条消息的到来。PeekMessage
以查看的方式从系统中获取消息,可以不将消息从系统中移除,是一个非阻塞函数。当系统无消息时,返回FALSE,继续执行后续程序(相当于只负责侦查而不负责处理消息)
BOOL PeekMessage( LPMSG lpMsg, //message informationHWND hWnd, //handle to windowUINT wMsgFilterMin, //first messageUINT wMsgFilterMax, //last messageUINT wRemoveMsg//移除标识,赋值PM_NOREMOVE或PM_REMOVE);
while(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);//将消息交给窗口处理函数来处理}
//将处理消息的while循环可以换一种高效的写法了while(1){if(PeekMessage(&nMsg,NULL,0,0,PM_NOREMOVE)){//有消息if(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);}else{return 0;}}else{//空闲处理WriteConsole(g_hOutput,"OnIdle",strlen("OnIdle"),NULL,NULL);}}
示例:
#include <windows.h>
#include <stdio.h>HANDLE g_hOutput = 0;//接收标准输出句柄
void onSize(HWND hWnd, LPARAM lParam){short nWidth = LOWORD(lParam);short nHight = HIWORD(lParam);char szText[256] = {0};sprintf(szText, "WM_SIZE:宽:%d,高:%d\n", nWidth, nHight);WriteConsole(g_hOutput, szText,strlen(szText),NULL,NULL);
}void onCreate(HWND hWnd, LPARAM lParam){CREATESTRUCT* psc = (CREATESTRUCT*)lParam;char* pszText = (char*)psc->lpCreateParams;MessageBox(NULL, pszText,"Info",MB_OK);//创建子窗口CreateWindowEx(0,"EDIT","hello",WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,200,200,hWnd,NULL,0,NULL);
}
//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_SIZE:onSize(hWnd, lParam);break;case WM_CREATE://onCreate(hWnd, lParam);break;case WM_DESTROY:PostQuitMessage(0);//可以使GetMessage函数返回0break;case WM_SYSCOMMAND:if(wParam == SC_CLOSE){MessageBox(hWnd,"是否退出","Info",MB_YESNO);}else{return 0;}break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{AllocConsole();//增加一个DOC窗口g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//注册窗口类WNDCLASS wc = {0};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Main";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口char* pszText = "hello data";HWND hWnd = CreateWindowEx(0,"Main","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,pszText);//子窗口窗口类wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Child";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 = CreateWindowEx(0,"Child","c1",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 = CreateWindowEx(0,"Child","cc",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(1){if(PeekMessage(&nMsg,NULL,0,0,PM_NOREMOVE)){//有消息if(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);}else{return 0;}}else{//空闲处理WriteConsole(g_hOutput,"OnIdle",strlen("OnIdle"),NULL,NULL);}}return 0;
}
02 发送消息
- 消息的处理过程
SendMessage
发送消息,会等候消息处理的结果PostMessage
投递消息,消息发出后立即返回,不等待消息执行结果
LRESULT SendMessage / PostMessage( HWND hWnd, //消息发送的目的窗口UINT Msg, //消息IDWPARAM wParam,//消息参数 LPARAM lParam //消息参数
);
#include <windows.h>
#include <stdio.h>HANDLE g_hOutput = 0;//接收标准输出句柄
void onSize(HWND hWnd, LPARAM lParam){short nWidth = LOWORD(lParam);short nHight = HIWORD(lParam);char szText[256] = {0};sprintf(szText, "WM_SIZE:宽:%d,高:%d\n", nWidth, nHight);WriteConsole(g_hOutput, szText,strlen(szText),NULL,NULL);
}void onCreate(HWND hWnd, LPARAM lParam){CREATESTRUCT* psc = (CREATESTRUCT*)lParam;char* pszText = (char*)psc->lpCreateParams;MessageBox(NULL, pszText,"Info",MB_OK);//创建子窗口CreateWindowEx(0,"EDIT","hello",WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,200,200,hWnd,NULL,0,NULL);
}
//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_SIZE:onSize(hWnd, lParam);break;case WM_CREATE://onCreate(hWnd, lParam);break;case WM_DESTROY://PostQuitMessage(0);//可以使GetMessage函数返回0//窗口能顺利关闭,说明GetMessage能抓到PostMessage发送的消息PostMessage(hWnd, WM_QUIT, 0, 0);//PostQuitMessage内部调用此函数//窗口不能顺利关闭,说明GetMessage不能抓到SendMessage发送的消息//SendMessage(hWnd, WM_QUIT, 0, 0);break;case WM_SYSCOMMAND:if(wParam == SC_CLOSE){MessageBox(hWnd,"是否退出","Info",MB_YESNO);}else{return 0;}break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{AllocConsole();//增加一个DOC窗口g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//注册窗口类WNDCLASS wc = {0};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Main";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口char* pszText = "hello data";HWND hWnd = CreateWindowEx(0,"Main","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,pszText);//子窗口窗口类wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Child";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 = CreateWindowEx(0,"Child","c1",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 = CreateWindowEx(0,"Child","cc",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(1){if(PeekMessage(&nMsg,NULL,0,0,PM_NOREMOVE)){//有消息if(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);}else{return 0;}}else{//空闲处理WriteConsole(g_hOutput,"OnIdle",strlen("OnIdle"),NULL,NULL);}}return 0;
}
03消息分类
- 系统消息:ID范围
0-0x3FF
,由系统定义好的消息,可以在程序中直接使用(注意系统消息要么程序员只负责处理不负责发送,如WM_SIZE,要么只负责发送不负责处理,如WM_QUIT) - 用户自定义消息:ID范围
0x0400-0x7FFF(31743)'
- 由用户自己定义,满足用户自己的需求,由用户自己发出消息,并相应处理
- 自定义消息宏:
WM_USER
自定义消息示例
#include <windows.h>
#include <stdio.h>
//自定义消息
#define WM_MYMESSAGE WM_USER+1001HANDLE g_hOutput = 0;//接收标准输出句柄
void onSize(HWND hWnd, LPARAM lParam){short nWidth = LOWORD(lParam);short nHight = HIWORD(lParam);char szText[256] = {0};sprintf(szText, "WM_SIZE:宽:%d,高:%d\n", nWidth, nHight);WriteConsole(g_hOutput, szText,strlen(szText),NULL,NULL);
}void onCreate(HWND hWnd, LPARAM lParam){CREATESTRUCT* psc = (CREATESTRUCT*)lParam;char* pszText = (char*)psc->lpCreateParams;MessageBox(NULL, pszText,"Info",MB_OK);//发送自定消息(自己爱在哪里发送就写在哪里)PostMessage(hWnd,WM_MYMESSAGE,1,2);//创建子窗口CreateWindowEx(0,"EDIT","hello",WS_CHILD|WS_VISIBLE|WS_BORDER,0,0,200,200,hWnd,NULL,0,NULL);
}void onMyMessage(HWND hWnd, WPARAM wParam, LPARAM lParam){char szText[256] = {0};sprintf(szText,"自定义消息被处理:wParam=%d,lParam=%d\n", wParam, lParam);MessageBox(hWnd, szText, "Infor", MB_OK);
}
//窗口处理函数(自定义,处理函数)
LRESULT CALLBACK WndProc(HWND hWnd,UINT msgID,WPARAM wParam,LPARAM lParam)
{switch(msgID){case WM_MYMESSAGE:onMyMessage(hWnd,wParam, lParam);break;case WM_SIZE:onSize(hWnd, lParam);break;case WM_CREATE://onCreate(hWnd, lParam);break;case WM_DESTROY://PostQuitMessage(0);//可以使GetMessage函数返回0//窗口能顺利关闭,说明GetMessage能抓到PostMessage发送的消息PostMessage(hWnd, WM_QUIT, 0, 0);//PostQuitMessage内部调用此函数//窗口不能顺利关闭,说明GetMessage不能抓到SendMessage发送的消息//SendMessage(hWnd, WM_QUIT, 0, 0);break;case WM_SYSCOMMAND:if(wParam == SC_CLOSE){MessageBox(hWnd,"是否退出","Info",MB_YESNO);}else{return 0;}break;}return DefWindowProc(hWnd, msgID, wParam, lParam);//给各种消息默认处理
}
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns,LPSTR lpCmdLine,int nCmdShow)
{AllocConsole();//增加一个DOC窗口g_hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//注册窗口类WNDCLASS wc = {0};wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Main";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//在内存创建窗口char* pszText = "hello data";HWND hWnd = CreateWindowEx(0,"Main","window",WS_OVERLAPPEDWINDOW,100,100,500,500,NULL,NULL,hIns,pszText);//子窗口窗口类wc.cbClsExtra = 0;wc.cbWndExtra = 0;wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);wc.hCursor = NULL;wc.hIcon = NULL;wc.hInstance = hIns;wc.lpfnWndProc = WndProc;wc.lpszClassName = "Child";wc.lpszMenuName = NULL;wc.style = CS_HREDRAW|CS_VREDRAW;RegisterClass(&wc);//将以上所有赋值全部写入操作系统内核//子窗口1HWND hChild1 = CreateWindowEx(0,"Child","c1",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,0,0,200,200,hWnd,NULL,hIns,NULL);//子窗口2HWND hChild2 = CreateWindowEx(0,"Child","cc",WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE,200,0,200,200,hWnd,NULL,hIns,NULL);//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);//消息循环MSG nMsg = {0};while(1){if(PeekMessage(&nMsg,NULL,0,0,PM_NOREMOVE)){//有消息if(GetMessage(&nMsg,NULL,0,0)){TranslateMessage(&nMsg);DispatchMessage(&nMsg);}else{return 0;}}else{//空闲处理WriteConsole(g_hOutput,"OnIdle",strlen("OnIdle"),NULL,NULL);}}return 0;
}
相关文章:

Windows窗口
Windows窗口 Unit01注册窗口类 01窗口类的概念 窗口类是包括了窗口的各种参数信息的数据结构每个窗口都具有窗口类,基于窗口类创建窗口每个窗口都具有一个名称,使用前必须注册到系统 02窗口类的分类 系统窗口类 系统已经定义好的窗口类,…...

Spring Transaction 源码解读
Spring Transaction 规范的maven坐标如下: <dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>...</version></dependency>该包提供了spring事务规范和默认的jta(ja…...

[Netty] Channel和ChannelFuture和ChannelFutureListener (六)
文章目录1.Channel介绍2.ChannelFuture接口介绍3.GenericFutureListener接口介绍1.Channel介绍 NIO的Channel与Netty的Channel 不一样 Netty重新设计了Channel接口,并且给予了很多不同的实现, Channel是Netty网络的抽象类, 除了NIO中Channel所包含的网络I/O操作, 主动建立和关…...

条件渲染
组件经常需要根据不同条件显示不同内容。在React中,你可以使用类似于if语句、&&和?:运算符的JavaScript语法有条件地呈现JSX。你将学到:如何根据条件返回不同的JSX如何有条件地包含或排除一段JSX在React代码库中常见的条件语法快捷方式有条件地…...
springboot(10)异步任务
文章目录1、SpringBoot异步任务1.1使用注解EnableAsync开启异步任务支持1.2使用Async注解标记要进行异步执行的方法1.3controller测试2.异步任务相关限制3.1自定义 Executor3.1.1应用层级:3.1.2方法层级:3.2自定义 Executor (第二种方式)4.1异常处理4.1.…...
清华大学开源的chatGLM-6B部署实战
Windows部署 win10 通过wsl部署 常见问题: torch.cuda.OutOfMemoryError: CUDA out of memory. 在Windows的系统环境变量中增加 变量名:PYTORCH_CUDA_ALLOC_CONF 变量值:max_split_size_mb:32 文档书写时使用3090 24G显存配置,其他规格酌情调整 32 至其他值,如未设置变…...
通过矩阵从整体角度搞懂快速傅里叶变换原理
离散傅里叶变换公式 公式 f[k]∑n0N−1g[n]e−i(2π/N)kn,其中(0<n<N)f[k]\sum_{n0}^{N-1}g[n]e^{-i(2\pi/N)kn}, 其中(0<n<N) f[k]n0∑N−1g[n]e−i(2π/N)kn,其中(0<n<N) 逆变换公式 g[n]1N∑k0N−1f[k]ei(2π/N)kn,其中(0<k<N)g[n]\frac{1}{N}\…...
【C++从0到1】25、C++中嵌套使用循环
C从0到1全系列教程 1、实例代码 #include <iostream> // 包含头文件。 using namespace std; // 指定缺省的命名空间。int main() {// 超女分4个小组,每个小组有3名超女,在控制台显示每个超女的小组编号和组内编号。// 用一个循环…...

FastDFS与Nginx结合搭建文件服务器,并内网穿透实现公网访问
文章目录前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.1 …...

密集场景下的行人跟踪替代算法,头部跟踪算法 | CVPR 2021
一个不知名大学生,江湖人称菜狗 original author: Jacky LiEmail : 3435673055qq.com Time of completion:2023.4.8 Last edited: 2023.4.8 目录 摘要 主要内容 结果 这篇文章是CVPR 2021 的最新论文,文章的标题: 文章的主要内…...

Matlab与ROS(1/2)---服务端和客户端数据通信(五)
0. 简介 在前几讲我们讲了Matlab中的Message以及Topic的相关知识。而ROS主要支持的通信机制还有服务这一类。服务通过允许请求以及响应的通信方式,来给整个系统完成更紧密的耦合。服务客户端向服务服务器发送请求消息并等待响应。服务器将使用请求中的数据构造响应…...
数字化转型的避坑指南:细说数字化转型十二大坑
随着信息技术的快速发展,数字化转型已经成为许多企业发展的必经之路。然而,数字化转型过程中也存在许多坑,如果不谨慎处理,就可能导致企业陷入困境。本文将细说数字化转型的十二大坑,并提供相应的避坑指南。 1、不了解…...
pt05Encapsulationinherit
Encapsulation &inherit 封装继承 封装 向类外提供必要的功能,隐藏实现的细节, 代码可读性更高优势:简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。私有成员:作用:无需向类外提供…...

面向对象编程(基础)9:封装性(encapsulation)
目录 9.1 为什么需要封装? 而“高内聚,低耦合”的体现之一: 9.2 何为封装性? 9.3 Java如何实现数据封装 9.4 封装性的体现 9.4.1 成员变量/属性私有化 实现步骤: 成员变量封装的好处: 9.4.2 私有化…...
fate-serving-server增加取数逻辑并源码编译
1.什么是fate-serving-server? FATE-Serving 是一个高性能、工业化的联邦学习模型服务系统,专为生产环境而设计,主要用于在线推理。 2.fate-serving-server源码编译 下载fate-serving-serving项目(GitHub - FederatedAI/FATE-Serving: A scalable, h…...

循环队列、双端队列 C和C++
队列 目录 概念 实现方式 顺序队列 循环队列 队列的数组实现 用循环链表实现队列 STL 之 queue 实现队列 STL 之 dequeue 实现双端队列 概念 队列是一种特殊的线性表,它只允许在表的前端(称为队头,front)进行删除操作…...
正则表达式(语法+例子)
文章目录一、介绍二、语法1、匹配字符2、表示数量的字符3、边界字符4、其他字符5、转义字符三、例子1、邮箱2、用逗号分隔的数字集合1,23、允许一位小数4、20yy-mm-dd日期格式5、手机号6、匹配html、xml标签一、介绍 正则表达式(Regular Expression)&am…...

Properties和IO流集合的方法
方法名说明void load(InputStream inStream)从输入字节流读取属性列表(键和元素)void load(Reader reader)从输入字符流读取属性列表(键和元素对)void store(OutputStream out,String comments)将此属性列表(键和元素对…...

python 生成器、迭代器、动态新增属性及方法
目录 一、生成器 1、生成器定义 2、生成器存在的意义 3、创建生成器方式一(生成器表达式) 4. 创建生成器方式二(生成器函数) 1. 生成器函数 2. 生成器函数的工作原理 5. 总结 1. 什么是生成器 2. 生成器特点 二、迭代器…...
Java处理JSON
Java处理json有很多种方法,在这里总结一下。 1 Jackson Spring MVC 默认采用Jackson解析Json,出于最小依赖的考虑,也许Json解析第一选择就应该是Jackson。 1.1 引入的包 Jackson核心模块由三部分组成:jackson-core、jackson-a…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...

Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...