SDK 控件

news2024/12/24 22:15:13

目录

控件

控件创建

控件的消息处理

总代码


本篇文章对控件的学习,只是对基础的部分,简单的使用,包括消息的处理上,并不涉及深入的内容。

控件

区分控件,资源:

SDK通常提供了一系列常用的用户界面控件,如按钮、文本框、列表框、组合框等。开发人员可以使用这些控件来构建应用程序的用户界面。SDK通常提供了各种图像、图标和光标资源,开发人员可以使用这些资源来美化应用程序的用户界面。

控件的使用很方便,直接拖过去即可

程序员只需要处理好这些控件的消息也就是(ID)即可

所有控件消息都是WM_COMMAND,各种不同消息的区分就要靠 wParam,lParam这两个参数的信息

一些常用控件的学习可以参考:SDK05- 控件_黑桃鱼的博客-CSDN博客

他人珠玉在前,不再献丑

控件创建

创建控件其实也就是创建一个窗口,指定一个父窗口即可,同时安排好控件的大小位置

按钮一

	// 创建子窗口(控件)控件的操作都会产生Command消息
	HWND hButton1 = CreateWindowEx(0,
		_T("BUTTON"),
		_T("是否打勾"),
		WS_CHILD | WS_VISIBLE | BS_CHECKBOX | LBS_NOTIFY,  //组合属性,可拉伸窗口
		0,
		0,
		100,
		50,
		hWnd,
		(HMENU)IDB_BUTTON1,
		g_hInstance,
		NULL);

按钮二

	HWND hButton2 = CreateWindowEx(0,
		_T("BUTTON"),
		_T("粘贴"),
		WS_CHILD | WS_VISIBLE, // 还可以给按加别的样式BS_开头
		100,                    //按钮可打勾
		0,
		100,
		50,
		hWnd,
		(HMENU)IDB_BUTTON2,
		g_hInstance,
		NULL);

编辑框

	HWND hEdit = CreateWindowEx(0,
		_T("Edit"),
		NULL,
		WS_CHILD | WS_VISIBLE | WS_VSCROLL |
		ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,  //组合属性,可拉伸窗口
		0,     // ws通用 es Edit控件单独有的
		60,
		200,
		100,
		hWnd,
		(HMENU)IDE_Edit1,
		g_hInstance,
		NULL);

列表

	HWND hListBox = CreateWindowEx(0,
		_T("ListBox"),
		_T("编程语言列表"),
		WS_CHILD | WS_VISIBLE | WS_VSCROLL | LBS_HASSTRINGS,  //组合属性,可拉伸窗口
		0,     // ws通用 es Edit控件单独有的
		200,
		200,
		100,
		hWnd,
		(HMENU)IDL_LISTBOX,
		g_hInstance,
		NULL);

控件的消息处理

控件的消息都会被转换成WM_COMMAND消息

代码如下:

lParam是控件的句柄,在逻辑中就是先判断是控件的消息,控件句柄是否为空,是控件的消息的话,再更具wParam的低字(控件标识符)来进一步区分是哪一个控件,wParam的高字则是消息,再去进一步处理

LRESULT OnCommand(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	OutputDebugString(_T("[51asm] OnCommand\n"));
	WORD wID = LOWORD(wParam);
	WORD wNotifyCode = HIWORD(wParam);
	HWND hColtrol = (HWND)lParam;
	if (hColtrol != NULL) { //控件
		if (wID == IDB_BUTTON1) {
			if (wNotifyCode == BN_CLICKED) {
				LRESULT Result = SendMessage(hColtrol, BM_GETCHECK, 0, 0);
				if (BST_CHECKED == Result) {
					SendMessage(hColtrol, BM_SETCHECK, BST_UNCHECKED, NULL);
					MessageBox(NULL, _T("未婚"), _T("婚姻状况"), MB_OK);
				}
				else if (BST_UNCHECKED == Result) {
					SendMessage(hColtrol, BM_SETCHECK, BST_CHECKED, NULL);
					MessageBox(NULL, _T("已婚"), _T("婚姻状况"), MB_OK);
				}
			}
		}
		else if (wID == IDB_BUTTON2) {
			if (wNotifyCode == BN_CLICKED) {
				HWND hEdit = GetDlgItem(hwnd, IDE_Edit1);
				char szText[] = { "" };
				SendMessage(hEdit, WM_SETTEXT, 0, (LPARAM)szText); // 直接调用窗口过程函数,知道过程函数返回,否则就会一直卡在这里
				SendMessage(hEdit, WM_PASTE, 0, 0);
			}
		}
		
		if (wID == IDL_LISTBOX && wNotifyCode == LBN_SELCHANGE) {
			int nIndex = SendMessage(hColtrol, LB_GETCURSEL, 0, 0);
			if (nIndex != -1) {
				int nLen = SendMessage(hColtrol, LB_GETTEXTLEN, nIndex, 0);
				LPVOID lpBuff = malloc(nLen+1);
				SendMessage(hColtrol, LB_GETTEXT, nIndex, (LPARAM)lpBuff);
				MessageBoxA(hwnd, (char*)lpBuff, "51asm", MB_OK);
				free(lpBuff);
			}
		}
		return TRUE;
	}

	switch (wID) {
	case IDM_OPEN:
		MessageBox(NULL, _T("打开"), _T("51asm"), MB_OK);
		break;
	case IDM_SAVE:
		MessageBox(NULL, _T("保存"), _T("51asm"), MB_OK);
	case IDM_EXIT:
		SendMessage(hwnd, WM_USER + 1, NULL, NULL);// 向窗口发送一个消息
		PostQuitMessage(0); // 给自己投递QUIT消息
		// 操作窗口,想窗口发消息  WM_USER 0x0400开始
		//SendMessage(hwnd,WM_USER+1,NULL,NULL);// 向窗口发送一个消息
		break;
	}
	
	return TRUE;
}

总代码

#include <windows.h>
#include <tchar.h>
#include <fstream>
#include <string>

#ifdef _DEBUG
	#define MYOUTPUT OutputDebugString
#else 
	#define MYOUTPUT
#endif // DEBUG



#define IDM_OPEN 102
#define IDM_SAVE 103
#define IDM_EXIT 104

#define IDB_BUTTON1 105
#define IDB_BUTTON2 106
#define IDE_Edit1 107
#define IDL_LISTBOX 108

#define MY_MSG WM_USER+1  // 用户自定义消息

using namespace std;

string g_Text;
TEXTMETRIC g_tm; // 字体信息

HINSTANCE g_hInstance = NULL;


void ShowErrorMsg() {
	LPVOID lpMsgBuf;
	FormatMessage(
		FORMAT_MESSAGE_ALLOCATE_BUFFER |
		FORMAT_MESSAGE_FROM_SYSTEM |
		FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		GetLastError(),
		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
		(LPTSTR)&lpMsgBuf,
		0,
		NULL
	);
	MessageBox(NULL, (LPCTSTR)lpMsgBuf, _T("ERROR"), MB_OK | MB_ICONINFORMATION);
	LocalFree(lpMsgBuf);
}


LRESULT OnCreate(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	OutputDebugString(_T("[51asm]: WM_Create\n"));

	// 创建一个定时器,有两种调用方式,100毫秒画一次
// 	SetTimer(hwnd, 1, 1000, nullptr);
// 	SetTimer(hwnd, 2, 1000, nullptr);

	return TRUE;
}

// 当你关闭窗口点击确定后就会向窗口发送WM_Destroy消息,就意味要销毁窗口,
LRESULT OnClose(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	OutputDebugString(_T("[51asm]: WM_Close\n"));
	return FALSE;
}

// 这个工作可以交给系统处理,也可以自己处理
LRESULT OnDestroy(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	OutputDebugString(_T("[51asm]: WM_Destory\n"));
	PostQuitMessage(0);

	// 销毁定时器,倘若有多个窗口,销毁一个窗口而不是全部
	KillTimer(hwnd, 1);


	return TRUE;
}



LRESULT OnCommand(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	OutputDebugString(_T("[51asm] OnCommand\n"));
	WORD wID = LOWORD(wParam);
	WORD wNotifyCode = HIWORD(wParam);
	HWND hColtrol = (HWND)lParam;
	if (hColtrol != NULL) { //控件
		if (wID == IDB_BUTTON1) {
			if (wNotifyCode == BN_CLICKED) {
				LRESULT Result = SendMessage(hColtrol, BM_GETCHECK, 0, 0);
				if (BST_CHECKED == Result) {
					SendMessage(hColtrol, BM_SETCHECK, BST_UNCHECKED, NULL);
					MessageBox(NULL, _T("未婚"), _T("婚姻状况"), MB_OK);
				}
				else if (BST_UNCHECKED == Result) {
					SendMessage(hColtrol, BM_SETCHECK, BST_CHECKED, NULL);
					MessageBox(NULL, _T("已婚"), _T("婚姻状况"), MB_OK);
				}
			}
		}
		else if (wID == IDB_BUTTON2) {
			if (wNotifyCode == BN_CLICKED) {
				HWND hEdit = GetDlgItem(hwnd, IDE_Edit1);
				char szText[] = { "" };
				SendMessage(hEdit, WM_SETTEXT, 0, (LPARAM)szText); // 直接调用窗口过程函数,知道过程函数返回,否则就会一直卡在这里
				SendMessage(hEdit, WM_PASTE, 0, 0);
			}
		}
		
		if (wID == IDL_LISTBOX && wNotifyCode == LBN_SELCHANGE) {
			int nIndex = SendMessage(hColtrol, LB_GETCURSEL, 0, 0);
			if (nIndex != -1) {
				int nLen = SendMessage(hColtrol, LB_GETTEXTLEN, nIndex, 0);
				LPVOID lpBuff = malloc(nLen+1);
				SendMessage(hColtrol, LB_GETTEXT, nIndex, (LPARAM)lpBuff);
				MessageBoxA(hwnd, (char*)lpBuff, "51asm", MB_OK);
				free(lpBuff);
			}
		}
		return TRUE;
	}

	switch (wID) {
	case IDM_OPEN:
		MessageBox(NULL, _T("打开"), _T("51asm"), MB_OK);
		break;
	case IDM_SAVE:
		MessageBox(NULL, _T("保存"), _T("51asm"), MB_OK);
	case IDM_EXIT:
		SendMessage(hwnd, WM_USER + 1, NULL, NULL);// 向窗口发送一个消息
		PostQuitMessage(0); // 给自己投递QUIT消息
		// 操作窗口,想窗口发消息  WM_USER 0x0400开始
		//SendMessage(hwnd,WM_USER+1,NULL,NULL);// 向窗口发送一个消息
		break;
	}
	
	return TRUE;
}


BOOL InitControl(HWND hWnd) {
	// 创建子窗口(控件)控件的操作都会产生Command消息
	HWND hButton1 = CreateWindowEx(0,
		_T("BUTTON"),
		_T("是否打勾"),
		WS_CHILD | WS_VISIBLE | BS_CHECKBOX | LBS_NOTIFY,  //组合属性,可拉伸窗口
		0,
		0,
		100,
		50,
		hWnd,
		(HMENU)IDB_BUTTON1,
		g_hInstance,
		NULL);

	HWND hButton2 = CreateWindowEx(0,
		_T("BUTTON"),
		_T("粘贴"),
		WS_CHILD | WS_VISIBLE, // 还可以给按加别的样式BS_开头
		100,                    //按钮可打勾
		0,
		100,
		50,
		hWnd,
		(HMENU)IDB_BUTTON2,
		g_hInstance,
		NULL);

	HWND hEdit = CreateWindowEx(0,
		_T("Edit"),
		NULL,
		WS_CHILD | WS_VISIBLE | WS_VSCROLL |
		ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL,  //组合属性,可拉伸窗口
		0,     // ws通用 es Edit控件单独有的
		60,
		200,
		100,
		hWnd,
		(HMENU)IDE_Edit1,
		g_hInstance,
		NULL);


	
	HWND hListBox = CreateWindowEx(0,
		_T("ListBox"),
		_T("编程语言列表"),
		WS_CHILD | WS_VISIBLE | WS_VSCROLL | LBS_HASSTRINGS,  //组合属性,可拉伸窗口
		0,     // ws通用 es Edit控件单独有的
		200,
		200,
		100,
		hWnd,
		(HMENU)IDL_LISTBOX,
		g_hInstance,
		NULL);

	SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)"C语言");
	SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)"C++");
	SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)"C数据结构");



	// 操作控件发消息
	SendMessage(hButton1, BM_SETCHECK, BST_UNCHECKED, NULL);
	return TRUE;

}



LRESULT OnKeyDown(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	OutputDebugString(_T("[51asm]: OnKeyDown\n"));
	return TRUE;
}



LRESULT OnKeyUp(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	OutputDebugString(_T("[51asm]: OnKeyUp\n"));
	return TRUE;
}


// 定时器消息
LRESULT OnTimer(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	if (wParam == 1) {
		MYOUTPUT(_T("[51asm]: OnTimer\n"));
		HWND hDesktop = GetDesktopWindow();
		HDC hdc = GetDC(hDesktop);
		TextOut(hdc, 0, 0, _T("51asm"), 5);
		ReleaseDC(hDesktop,hdc);
		//CloseHandle(hDesktop); GetDesktopWinodw()函数的句柄不需要用户释放
		MYOUTPUT(_T("[51asm]: OnTimer ID=1 \n"));
	}
	else if (wParam == 2){
		MYOUTPUT(_T("[51asm]: OnTimer ID=2 \n"));
	}
	return TRUE;
}


LRESULT OnNotify(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	OutputDebugString(_T("[51asm]: OnNotify\n"));
	NMHDR* pnmh = (LPNMHDR)lParam;
	if (wParam == IDL_LISTBOX) {
		int nIndex = SendMessage(pnmh->hwndFrom, LB_GETCURSEL, 0, 0);
		if (nIndex != -1) {
			int nLen = SendMessage(pnmh->hwndFrom, LB_GETTEXTLEN, nIndex, 0);
			LPVOID lpBuff = malloc(nLen);
			SendMessage(pnmh->hwndFrom, LB_GETTEXT, nIndex, (LPARAM)lpBuff);
			MessageBoxA(hwnd, (char*)lpBuff, "51asm", MB_OK);
			free(lpBuff);
		}
	}
	return TRUE;
}



// 消息处理
// 可以下断点debug调试分析消息,在监视这里可以 uMsg.wm 可以以看到
// 先创建非客户区,再创建客户区,还有创建窗口等很多消息
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	LRESULT lResult = FALSE;

	switch (uMsg) {
	case WM_NOTIFY:
		lResult = OnNotify(hwnd, uMsg, wParam, lParam);
		break;
	case WM_CREATE:
		lResult = OnCreate(hwnd, uMsg, wParam, lParam); 
		break;
	case WM_CLOSE:
		lResult = OnClose(hwnd, uMsg, wParam, lParam);
		break;
	case WM_DESTROY:
		lResult = OnDestroy(hwnd, uMsg, wParam, lParam);
		break;
	case WM_COMMAND:   
		lResult = OnCommand(hwnd, uMsg, wParam, lParam);
		break;
	case WM_KEYDOWN:     
		lResult = OnKeyDown(hwnd, uMsg, wParam, lParam);
		break;
	case WM_KEYUP:    
		lResult = OnKeyUp(hwnd, uMsg, wParam, lParam);
		break;
	case WM_TIMER:
		lResult = OnTimer(hwnd, uMsg, wParam, lParam);
		break;
	case MY_MSG:
		MessageBox(NULL, _T("我的消息"), NULL, NULL);
	}

	if (!lResult) {
		return DefWindowProc(hwnd, uMsg, wParam, lParam); // 默认窗口过程处理函数,包括销毁窗口
	}
	return lResult;
}

/*
	客户区(用户区)与非客户区(系统的) NC


*/

int WINAPI wWinMain(
	HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPWSTR lpCmdLine,
	int nShowCmd
) {
	g_hInstance = hInstance;

	// 申请堆控件,因为快捷键需要全局访问
	// 申请100字节的局部堆地址空间
	// 这样设计的原因,内存空间申请释放,产生了很多碎片,通过把这些碎片整理得到一个更大的内存空间,这是地址变化了

	// 申请局部堆地址
	HLOCAL hMenu = LocalAlloc(LHND, 100);
	LPVOID lpMemory = LocalLock(hMenu);
	LocalFree(hMenu);


	// 申请全局堆地址
	// 原因:16位系统,有全局堆和局部堆;32位,两者合并,只有一个堆
	GlobalAlloc(LHND, 100);


	// 申请堆空间
	// 新的API,返回值是一个地址,前两个函数的底层是调用这个
	//HeapAlloc();

	// 申请堆地址空间,可以指定内存属性
	//VirtualAlloc();

	ACCEL* pAccelNews = (ACCEL*)HeapAlloc(GetProcessHeap(), 0, sizeof(ACCEL) * 2);

	if (pAccelNews == nullptr) {
		ShowErrorMsg();
		return 0;
	}
	
	
	// 快捷键,可以用下面的写法,把快捷键和菜单消息一起处理
// 	pAccelNews[0].fVirt = FALT | FCONTROL | FVIRTKEY;
// 	pAccelNews[0].key = 'A';
// 	pAccelNews[0].cmd = WM_COMMAND;

	// 
	pAccelNews[1].fVirt = FCONTROL | FVIRTKEY;
	pAccelNews[1].key = 'S';
	pAccelNews[1].cmd = IDM_SAVE;

	// 创建快捷键表
	HACCEL hAccel = CreateAcceleratorTable(pAccelNews, 2);
	
	if (hAccel == NULL) {
		ShowErrorMsg();
		return 0;
	}


	// 创建窗口实例
	TCHAR szWndClassName[] = { _T("CR41WndClassName") };

	WNDCLASSEX wc = { 0 };
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
	wc.lpfnWndProc = WindowProc;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(NULL, IDI_HAND);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = CreateSolidBrush(RGB(255, 255, 255));
	wc.lpszMenuName = NULL;
	wc.lpszClassName = szWndClassName;

	// 注册窗口
	if (RegisterClassEx(&wc) == 0) {
		ShowErrorMsg();
		return 0;
	}


	// 创建窗口
	TCHAR szWndName[] = { _T("51asm") };
	HWND hWnd = CreateWindowEx(0,
		szWndClassName,
		szWndName,
		WS_OVERLAPPEDWINDOW,  //组合属性,可拉伸窗口
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		NULL,
		NULL,
		hInstance,
		NULL);



	if (hWnd == NULL) {
		ShowErrorMsg();
		return 0;
	}

	// 菜单
	HMENU HMenu = CreateMenu();

	// 弹出菜单
	BOOL ret;
	ret = AppendMenu(HMenu, MF_STRING | MF_POPUP, (UINT_PTR)HMenu, _T("文件(&F)"));
	ret = AppendMenu(HMenu, MF_STRING | MF_POPUP, (UINT_PTR)HMenu, _T("编辑(&E)"));
	SetMenu(hWnd, HMenu);

	// 添加子菜单
	HMENU hSubMenu = GetSubMenu(HMenu, 0);
	ret = AppendMenu(hSubMenu, MF_STRING, IDM_OPEN, _T("打开(&O)"));
	ret = AppendMenu(hSubMenu, MF_STRING, IDM_SAVE, _T("保存(&O)"));
	ret = AppendMenu(hSubMenu, MF_STRING, IDM_EXIT, _T("退出(&O)"));

	SetMenu(hWnd, HMenu);


	RECT rc;
	GetClientRect(hWnd, &rc);


	// 创建子窗口(控件)
	InitControl(hWnd);



	// 显示,更新窗口
	ShowWindow(hWnd, SW_SHOWNORMAL); // 调用Show时候父子窗口都会被调用
	//ShowWindow(hChild, SW_SHOWNORMAL);  非子窗口需要单独show
	UpdateWindow(hWnd);  // 产生WM_PAINT

	SetClassLong(hWnd, GCL_HCURSOR, (LONG)LoadCursor(NULL, IDC_CROSS));




	// 消息循环
	BOOL bRet;
	MSG msg;
	while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
	{
		if (bRet == -1) {
			break;
		}
		else {
			// 转换快捷键消息 WM_COMMAND
			if (!TranslateAccelerator(hWnd, hAccel, &msg)) {
				TranslateMessage(&msg);// 转换键盘消息
				DispatchMessage(&msg); // 派发消息
			}
		}
	}

	// 删除快捷键表
	DestroyAcceleratorTable(hAccel);
	HeapFree(GetProcessHeap(), 0, pAccelNews);

	return msg.wParam;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1145131.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

san.js源码解读之模版解析(parseTemplate)篇——readIdent函数

一、源码分析 /*** 读取ident* 这里的 ident 指标识符(identifier)&#xff0c;也就是通常意义上的变量名* 这里默认的变量名规则为&#xff1a;由美元符号($)、数字、字母或者下划线(_)构成的字符串** inner* param {Walker} walker 源码读取对象* return {string}*/ functio…

虎去兔来(C++)

系列文章目录 进阶的卡莎C++_睡觉觉觉得的博客-CSDN博客数1的个数_睡觉觉觉得的博客-CSDN博客双精度浮点数的输入输出_睡觉觉觉得的博客-CSDN博客足球联赛积分_睡觉觉觉得的博客-CSDN博客大减价(一级)_睡觉觉觉得的博客-CSDN博客小写字母的判断_睡觉觉觉得的博客-CSDN博客纸币(…

python爬虫request和BeautifulSoup使用

request使用 1.安装request pip install request2.引入库 import requests3.编写代码 发送请求 我们通过以下代码可以打开豆瓣top250的网站 response requests.get(f"https://movie.douban.com/top250"&#xff09;但因为该网站加入了反爬机制&#xff0c;所以…

Python---练习:有一物,不知其数,三三数之余二,五五数之余三,七七数之余二,问物几何?

案例&#xff1a; 有一物&#xff0c;不知其数&#xff0c;三三数之余二&#xff0c;五五数之余三&#xff0c;七七数之余二&#xff0c;问物几何&#xff1f; 人话&#xff1a; 有一个数字&#xff0c;不知道具体是多少&#xff0c;用3去除剩2&#xff0c;用5去除剩3&#…

Vue 3.3.6 ,得益于WeakMap,比之前更快了

追忆往昔&#xff0c;穿越前朝&#xff0c;CSS也是当年前端三剑客之一&#xff0c;风光的很&#xff0c;随着前端跳跃式的变革&#xff0c;CSS在现代前端开发中似乎有点默默无闻起来。 不得不说当看到UnoCss之前&#xff0c;我甚至都还没听过原子化CSS[1]这个概念&#xff08;…

业界中说的快速原型法是什么

快速原型法是一种软件开发过程&#xff0c;其核心思想是在开发初期快速构建一个系统的原型&#xff0c;即一个工作模型&#xff0c;以便用户和开发者能够更好地理解系统的需求和功能。这种方法强调快速迭代和用户参与&#xff0c;目的是更早地发现和修正问题&#xff0c;从而提…

微软:Octo Tempest是最危险的金融黑客组织之一

导语 最近&#xff0c;微软发布了一份关于金融黑客组织Octo Tempest的详细报告。这个组织以其高级社交工程能力而闻名&#xff0c;专门针对从事数据勒索和勒索软件攻击的企业。Octo Tempest的攻击手段不断演变&#xff0c;目标范围也不断扩大&#xff0c;成为了电缆电信、电子邮…

回流重绘零负担,网页加载快如闪电

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! 目录 ⭐ 专栏简介 &#x1f4d8; 文章引言 一、回…

椭圆曲线点加的应用计算

一、点加应用 1.1 背景 假设一条椭圆曲线方程为 y^2 =x^3+ax+b确定这条椭圆曲线方程参数是p,a,b,G,n,h,除了参数a,b ,其他参数的意义 p为质数,(mod p)运算G为基点n为点G的阶h是椭圆曲线上所有点的个数m与n相除的商的整数部分1.2 方程(y^2 =x^3+x+6,P=11) 椭圆曲线方程y…

原始流,缓冲流性能比较

一.低级字节流一个一个字节复制 1.代码 package org.example;import java.io.*;public class day13 {//原视频路径private static final String file1 "D:\\temp\\day05\\改名.mp4";//目的视频路径private static final String file2 "D:\\temp\\day05\\不改…

消息队列中间件面试笔记总结RabbitMQ,Kafka,RocketMQ

文章目录 (一) Rabbit MQRabbitMQ 核心概念消息队列的作用Exchange(交换器)Broker&#xff08;消息中间件的服务节点&#xff09;如何保证消息的可靠性如何保证 RabbitMQ 消息的顺序性如何保证 RabbitMQ 高可用的&#xff1f;如何解决消息队列的延时以及过期失效问题消息堆积问…

服务运营 |论文解读: 住院病人“溢出”:一种近似动态规划方法

摘要 在住院床位管理中&#xff0c;医院通常会将住院病人分配到相对应的专科病房&#xff0c;但随着病人的入院和出院&#xff0c;可能会出现病人所需的专科病房满员&#xff0c;而其他病房却有空余床位的情况。于是就有了 "溢出 "策略&#xff0c;即当病人等候时间…

温湿度计传感器DHT11控制数码管显示verilog代码及视频

名称&#xff1a;温湿度计传感器DHT11控制数码管显示 软件&#xff1a;QuartusII 语言&#xff1a;Verilog 代码功能&#xff1a; 使用温湿度传感器DHT11采集环境的温度和湿度&#xff0c;并在数码管显示 本代码已在开发板验证 开发板资料&#xff1a; 大西瓜第一代FPGA升级…

leetCode 229. 多数元素 II + 摩尔投票法 + 进阶 + 优化空间

229. 多数元素 II - 力扣&#xff08;LeetCode&#xff09; 给定一个大小为 n 的整数数组&#xff0c;找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。 进阶&#xff1a;尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题。 &#xff08;1&#xff09;哈希表 class …

Android-宝宝相册(第四次作业)

第四次作业-宝宝相册 题目 用Listview建立宝宝相册&#xff0c;相册内容及图片可自行设定&#xff0c;也可在资料文件中获取。给出模拟器仿真界面及代码截图。 &#xff08;参考例4-8&#xff09; 创建工程项目 创建名为baby的项目工程&#xff0c;最后的工程目录结构如下图所…

Linux 基本语句_8_C语言_文件控制

为了解决多个进程同时操作一个文件&#xff0c;产生一些情况&#xff0c;通常对文件进行上锁&#xff0c;已解决对共享文件的竞争 对打开文件进行各种操作&#xff1a; int fcentl(int fd, int cmd, .../*arg*/如果cmd与锁操作有关&#xff0c;那么fcentl函数的第三个参数就要…

从Mysql架构看一条查询sql的执行过程

1. 通信协议 我们的程序或者工具要操作数据库&#xff0c;第一步要做什么事情&#xff1f; 跟数据库建立连接。 首先&#xff0c;MySQL必须要运行一个服务&#xff0c;监听默认的3306端口。在我们开发系统跟第三方对接的时候&#xff0c;必须要弄清楚的有两件事。 第一个就是通…

38基于matlab的期货预测,利用PSO优化SVM和未优化的SVM进行对比,得到实际输出和期望输出结果。

基于matlab的期货预测&#xff0c;利用PSO优化SVM和未优化的SVM进行对比&#xff0c;得到实际输出和期望输出结果。线性核函数、多项式、RBF核函数三种核函数任意可选&#xff0c;并给出均方根误差&#xff0c;相对误差等结果&#xff0c;程序已调通&#xff0c;可直接运行。 3…

哈希算法:哈希算法在分布式系统中有哪些应用?

文章来源于极客时间前google工程师−王争专栏。 哈希算法除了上篇的四个应用&#xff08;安全加密、数据校验、唯一标识、散列函数&#xff09;&#xff0c;还有三种应用&#xff1a;负载均衡、数据分片、分布式存储。 这三个应用都跟分布式系统有关。哈希算法是如何解决这些分…

Nginx的进程结构实例演示

可以参考《Ubuntu 20.04使用源码安装nginx 1.14.0》安装nginx 1.14.0。 nginx.conf文件中worker_processes 2;这条语句表明启动两个worker进程。 sudo /nginx/sbin/nginx -c /nginx/conf/nginx.conf开启nginx。 ps -ef | grep nginx看一下进程情况。 sudo /nginx/sbin/ng…