首页 > 系统相关 >windows

windows

时间:2024-05-29 17:00:42浏览次数:14  
标签:case NULL return windows int 线程 include

窗口控件

LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
{
	static HINSTANCE hInstance = NULL; // 通常这里不需要static,但如果您想在WM_CREATE之外获取它,可以这样做  

	switch (msgID)
	{
	case WM_CREATE:
		hInstance = (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE); // 获取当前实例句柄  

		CreateWindowW(L"BUTTON", L"按钮1", WS_CHILD | WS_VISIBLE, 100, 100, 80, 50, hWnd, (HMENU)ID_BUTTON1, hInstance, NULL);
		CreateWindowW(L"BUTTON", L"移动窗口", WS_CHILD | WS_VISIBLE, 190, 100, 80, 50, hWnd, (HMENU)ID_BUTTON2, hInstance, NULL);
		CreateWindowW(L"BUTTON", L"获取文本框内容", WS_CHILD | WS_VISIBLE, 280, 100, 120, 50, hWnd, (HMENU)ID_BUTTON3, hInstance, NULL);
		CreateWindowW(L"BUTTON", L"文本框内容", WS_CHILD | WS_VISIBLE, 300, 200, 120, 50, hWnd, (HMENU)ID_BUTTON4, hInstance, NULL);
		CreateWindowW(L"BUTTON", L"设置父窗口", WS_CHILD | WS_VISIBLE, 150, 150, 80, 50, hWnd, (HMENU)ID_BUTTON5, hInstance, NULL);
		break;

	case WM_CLOSE:
		DestroyWindow(hWnd);
		break;

	case WM_DESTROY:
		PostQuitMessage(0);
		break;

	case WM_COMMAND:
		WORD ctrlid = LOWORD(wParam);
		int x, y = 0;
		switch (ctrlid)
		{
		case ID_BUTTON1:
			MessageBox(hWnd, "按钮1被点击了", "信息", MB_OK);
			break;
		case ID_BUTTON2:
			RECT rect;
			GetClientRect(hWnd, &rect); // 注意:这将获取客户区的大小,而不是整个窗口   
			x = rand() % (rect.right - 80);
			y = rand() % (rect.bottom - 50);

			MoveWindow((HWND)lParam, x, y, 80, 50, TRUE);
			break;
		case ID_BUTTON3:
			WCHAR buff[100]{ 0 };
			MessageBox(hWnd, "设置文本框内容的按钮被点击了,但这里没有文本框", "信息", MB_OK);
			HWND IDBT = GetDlgItem(hWnd, ID_BUTTON4);
			GetWindowText(IDBT, (LPSTR)buff, 100);
			MessageBoxW(hWnd, buff, L"haa", MB_OK);
			break;
         case ID_BUTTON5:
			SetParent((HWND)lParam, (HWND)0x00010D74);
			break;

资源利用

			HCURSOR hcursor = LoadCursor(hInstance, LPCSTR(IDC_CURSOR1));
			GetClassLongW(hWnd, GCL_HCURSOR, (LONG)hcursor);
	wc.hCursor = LoadCursor(0, MAKEINTRESOURCE(IDC_CURSOR1));  
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);

对话框

#include<Windows.h>
#include <stdio.h>
#include <CommCtrl.h>
#include "resource.h"
INT_PTR CALLBACK Dlgproc
(
	HWND hWnd,
	UINT Umsg,
	WPARAM wParam,
	LPARAM lParam
)
{
	switch (Umsg)
	{
	case WM_INITDIALOG:
	{
		MessageBoxW(hWnd, L"创建成功", L"提示", MB_OK);
		break;
	}
	case WM_CLOSE:
	{
		DestroyWindow(hWnd);
		PostQuitMessage(0);
	}
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case 0x10:
			MessageBoxW(hWnd, L"BUTTON1", L"提示", MB_OK);
			break;
		case 0x20:
			MessageBoxW(hWnd, L"BUTTON2", L"提示", MB_OK);
			break;
		}
	default: {
		return FALSE;
	}
	}
	return TRUE;
}
int WINAPI WinMain
(
	HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nShowCmd
)
{
	HWND hWnd = CreateDialogW(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, Dlgproc);
	ShowWindow(hWnd, SW_SHOWNORMAL);
	MSG msg{ 0 };
	while (GetMessage(&msg, 0, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessageW(&msg);
	}

	return 0;
}

#include <CommCtrl.h>
#include "resource.h"
INT_PTR CALLBACK Dlgproc
(
	HWND hWnd,
	UINT Umsg,
	WPARAM wParam,
	LPARAM lParam
)
{
	switch (Umsg)
	{
	case WM_INITDIALOG:
	{
		MessageBoxW(hWnd, L"创建成功", L"提示", MB_OK);
		break;
	}
	case WM_CLOSE:
	{
		EndDialog(hWnd, 0);
	}
	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case 0x10:
			MessageBoxW(hWnd, L"BUTTON1", L"提示", MB_OK);
			break;
		case 0x20:
			MessageBoxW(hWnd, L"BUTTON2", L"提示", MB_OK);
			break;
		}
	default: {
		return FALSE;
	}
	}
	return TRUE;
}
int WINAPI WinMain
(
	HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nShowCmd
)
{
	DialogBoxW(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, Dlgproc);

	return 0;
}

点击按钮

		Button_SetCheck((HWND)IDD_DIALOG1, BST_UNCHECKED);

下拉框

		ComboBox_AddString(GetDlgItem(hwnd, IDC_COMBO1), L"选项1");
		ComboBox_AddString(GetDlgItem(hwnd, IDC_COMBO1), L"选项2");

进度条控制

INT_PTR CALLBACK Dlgproc(
	HWND hwnd,
	UINT Umsg,
	WPARAM wParam,
	LPARAM lParam
)
{
	switch (Umsg)
	{
	case WM_INITDIALOG:
		SendDlgItemMessageW(hwnd, IDC_PROGRESS1, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
		SendDlgItemMessageW(hwnd, IDC_SLIDER1, TBM_SETRANGE, TRUE, MAKELPARAM(0, 100));
		break;
	case WM_CLOSE:
		EndDialog(hwnd, 0);
		break;
	case WM_COMMAND:
		break;
	case WM_HSCROLL:
		if (GetDlgItem(hwnd, IDC_SLIDER1) == (HWND)lParam)
		{
			int Pos = SendMessageW((HWND)lParam, TBM_GETPOS, 0, 0);
			SendDlgItemMessageW(hwnd, IDC_PROGRESS1, PBM_SETPOS, Pos, 0);
		}
		break;
	default:
		return FALSE;
	}
	return TRUE;
}

动态链接库

cpp

#include "main.h"
typedef int (*func)(int a, int b);
int main()
{
	HMODULE hMOULE = LoadLibrary(L"MY_DLL.dll");
	func fun = (func)GetProcAddress(hMOULE, "func");
	printf("%d", fun(1, 2));
	return 0;
}
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
int func(int a, int b)
{
	return a + b;
}
BOOL APIENTRY DllMain(HMODULE hModule,
	DWORD  ul_reason_for_call,
	LPVOID lpReserved
)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

h

#ifndef PCH_H
#define PCH_H

// 添加要在此处预编译的标头
#include "framework.h"
extern "C" _declspec(dllexport) int func(int a, int b);
void Cmy_button::OnBnClicked()
//控件子窗口来处理消息  由于c++是通过对象来处理事件的,所以我们点击按钮需要通过创建按钮对象来实现
{
	// TODO: 在此添加控件通知处理程序代码
	MessageBox(L"子窗口控件处理"); //同时对于子窗口处理了的事件,父窗口将不会再一次进行处理
}

MFC的button窗户变换

void Cmy_button::OnBnClicked()
//控件子窗口来处理消息  由于c++是通过对象来处理事件的,所以我们点击按钮需要通过创建按钮对象来实现
{
	CRect fe{ 0 };
	CRect bu{ 0 };
	GetParent()->GetClientRect(fe);
	GetClientRect(bu);
	int x = rand() % (fe.Height() - bu.Height());
	int y = rand() % (fe.Width() - bu.Width());
	bu.MoveToXY(x, y);
	MoveWindow(bu);
}

通过点击获取单选框内容

void Cmy_Dialog::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	CString strbuff;
	UpdateData();
	GetDlgItemText(IDC_RADIO1 + m_radio, strbuff);
	MessageBox(strbuff);
}

内核:

image-20240516133856978

进程基础操作

#include <Windows.h>
#include <TlHelp32.h>
#include <iostream>
int main()
{
	//打开一个进程
	HANDLE QQmusic = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 22608);
	//结束一个进程
	TerminateProcess(QQmusic, 0);
	//遍历进程快照
	/*
    PROCESSENTRY32W processEntry32 = { sizeof(PROCESSENTRY32W) };
	HANDLE hprocess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	BOOL re = Process32First(hprocess, &processEntry32);
	if (re)
	{
		do
		{
			printf("进程ID=%d,进程名称=%ls\n", processEntry32.th32ProcessID, processEntry32.szExeFile);
		} while (Process32NextW(hprocess, &processEntry32));
	}
	*/
    
    
    //模块
    	MODULEENTRY32 moduleEntry32 = { sizeof(MODULEENTRY32) };
	HANDLE hprocess = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 29876);
	BOOL re = Module32FirstW(hprocess, &moduleEntry32);
	if (re)
	{
		do
		{
			printf("进程名称 = % ls\n", moduleEntry32.szExePath);
		} while (Module32NextW(hprocess, &moduleEntry32));
	}
	return 0;
}

进程间通信:

进程间通信实现的就是在独立的一个进程中实现不同进程的交互过程
这里我们通过创建一个进程来实现找到我们的另一个进程,并实现我们另一个进程的获取创建进程的消息内容

发送消息进程:

#include <Windows.h>
int main()
{
	HWND findWND = FindWindowW(NULL, L"chen");
	COPYDATASTRUCT copydate = { 0 };
	copydate.lpData = (LPVOID)L"发送成功";
	copydate.cbData = 10;
	SendMessageW(findWND, WM_COPYDATA, NULL, (LPARAM)&copydate);
	return 0;
}

通过发送进程来获取消息

#include <Windows.h>
#include"resource.h"
INT_PTR CALLBACK WinProc(
	HWND hwnd,
	UINT msg,
	WPARAM wPararm,
	LPARAM LPARAM
)
{
	PCOPYDATASTRUCT pCopyDate = (PCOPYDATASTRUCT)LPARAM;
	switch (msg)
	{
	case WM_COPYDATA:
		MessageBoxW(hwnd, (LPCWSTR)pCopyDate->lpData, L"提示", MB_OK);
		break;
	case WM_CLOSE:
		EndDialog(hwnd, 0);
		break;
	default:
		return FALSE;
	}
	return TRUE;
}
int WINAPI WinMain(
	HINSTANCE hInstance,
	HINSTANCE hPrestance,
	LPSTR lpCmdLine,
	int nShowCmd
)
{
	DialogBoxW(hInstance, (LPCWSTR)MAKEINTRESOURCE(IDD_DIALOG1), NULL, WinProc);
	return 0;
}

或者通过邮筒的形式mailslot利用先创建一个邮筒,然后通过邮筒接收邮件file,然后通过发送方发送邮递的形式发送邮件,从而使用我们的进程之间的内容交互

发送方:

#include <Windows.h>
int main()
{
	HANDLE mailsolt = CreateFile(L"\\\\.\\mailslot\\Chen", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (mailsolt == INVALID_HANDLE_VALUE)
	{
		MessageBox(NULL, L"错误的句柄", L"提示", MB_OK);
		return FALSE;
	}
	WCHAR buff[] = L"chen";
	DWORD sz;
	WriteFile(mailsolt, buff, 6, &sz, NULL);
	CloseHandle(mailsolt);
	return 0;
}

接收方:

#include <Windows.h>
int main()
{
	HANDLE hMainslot = CreateMailslot(L"\\\\.\\mailslot\\Chen", 100, MAILSLOT_WAIT_FOREVER, NULL);
	if (hMainslot == INVALID_HANDLE_VALUE)
	{
		MessageBox(NULL, L"错误的句柄", L"提示", MB_OK);
		return FALSE;
	}
	WCHAR buff[50]{ 0 };
	DWORD readSize;
	ReadFile(hMainslot, buff, 100, &readSize, NULL);
	MessageBoxW(0, buff, L"提示", MB_OK);
	CloseHandle(hMainslot);
	return 0;
}

线程

进程是分配资源的单位,线程是执行程序操作的单位,一个进程至少有一个线程来执行操作

同时主线程和次线程之间属于并行的结果,执行过程中是保持平等的,但是主线程结束之后会使得子线程无法进行

#include <Windows.h>
#include <iostream>
DWORD WINAPI ThreadProc(
	_In_ LPVOID lpParameter
)
{
	printf("回调函数执行了");
	return 0;
};
int main()
{
	HANDLE hThead = CreateThread(NULL, NULL, ThreadProc, 0, 0, NULL);
	while (1)
	{
		printf("线程");
	}
	return 0;
}

由于我们的线程是并行的,所有主线程存在多久,子线程就会执行多久

#include <Windows.h>
#include <iostream>
DWORD WINAPI ThreadProc(
	_In_ LPVOID lpParameter
)
{
	while (1)
	{
		printf("回调函数");
	}
	return 0;
} ;
int main()
{
	HANDLE hThead = CreateThread(NULL, NULL, ThreadProc, 0, 0, NULL);
	Sleep(2222);
	//	WaitForSingleObject(hThead, -1);
	return 0;
}
//这里的2222毫秒之间都会一直的打印“回调函数”

​ WaitForSingleObject(hThead, -1); waitforsingleobject函数是当满足传入的句柄的线程执行完成之后才会进入下一步

这样就可以通过子线程去控制主线程的时间了

image-20240527205722940

打开并关闭线程

#include <Windows.h>
#include <TlHelp32.h>
#include <iostream>
DWORD WINAPI ThreadProc(
	_In_ LPVOID lpParameter
)
{
	int i = 0;
	while (i < 100)
	{
		printf("回调函数");
		i++;
	}
	return 0;
};
int main()
{
	HANDLE hThreadList = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
	THREADENTRY32 threadInfo{ sizeof(THREADENTRY32) };
	BOOL issucess = Thread32First(hThreadList, &threadInfo);
	if (issucess)
	{
		do
		{
			if (threadInfo.th32OwnerProcessID == 23672)
			{
				printf("线程ID:%d\n", threadInfo.th32ThreadID);
				HANDLE thread1 = OpenThread(THREAD_ALL_ACCESS, NULL, threadInfo.th32ThreadID);
				SuspendThread(thread1);
			}
		} while (Thread32Next(hThreadList, &threadInfo));
	}
	return 0;
}

线程同步:

相同的线程程序,可能执行次数是不同的,由于进程分配的资源有限的同时,cup的执行过程可能也会存在问题,会导致对同一个变量的相同操作执行出不同的结果

#include <Windows.h>
#include <iostream>
size_t g_count = 0;
DWORD WINAPI ThreadProc1(
	_In_ LPVOID lpParameter
)
{
	for (size_t i = 0; i < 100000; i++)
	{
		g_count++;
	}
	return 0;
}
DWORD WINAPI ThreadProc2(
	_In_ LPVOID lpParameter
)
{
	for (size_t i = 0; i < 100000; i++)
	{
		g_count++;
	}
	return 0;
}
int main()
{
	HANDLE Tread1 = CreateThread(NULL, 100, ThreadProc1, NULL, 0, NULL);
	HANDLE Tread2 = CreateThread(NULL, 100, ThreadProc2, NULL, 0, NULL);
	WaitForSingleObject(Tread1, INFINITE);
	WaitForSingleObject(Tread1, INFINITE);
	printf("%d", g_count);
	return 0;
}
/*方法:
1. 我们可以使用InterlockedIncrement(&g_count);将变量锁入临界区再cup一一处理之后再让另外的线程使用临界区资源
2. 我们直接创建临界区,让一个个线程通过临界区去执行代码
	for (size_t i = 0; i < 100000; i++)
	{
		EnterCriticalSection(&Critical_area);
		g_count++;
		LeaveCriticalSection(&Critical_area);
	}
	return 0;
*/

线程之间的执行情况是不同了,不同的线程可能每次执行的顺序也不一样

#include <Windows.h>
#include <iostream>
size_t g_count = 0;
HANDLE hEvent;
CRITICAL_SECTION Critical_area{ 0 };
DWORD WINAPI ThreadProc1(
	_In_ LPVOID lpParameter
)
{
	printf("线程一");
	return 0;
}
DWORD WINAPI ThreadProc2(
	_In_ LPVOID lpParameter
)
{
	printf("线程二");
	return 0;
}
DWORD WINAPI ThreadProc3(
	_In_ LPVOID lpParameter
)
{
	printf("线程三");
	return 0;
}
int main()
{
	InitializeCriticalSection(&Critical_area);
	HANDLE Tread1 = CreateThread(NULL, 100, ThreadProc1, NULL, 0, NULL);
	HANDLE Tread2 = CreateThread(NULL, 100, ThreadProc2, NULL, 0, NULL);
	HANDLE Tread3 = CreateThread(NULL, 100, ThreadProc3, NULL, 0, NULL);
	WaitForSingleObject(Tread1, -1);
	WaitForSingleObject(Tread2, -1);
	WaitForSingleObject(Tread3, -1);
	DeleteCriticalSection(&Critical_area);
	return 0;
}//线程一二三先执行都有可能

event

这时我们就可以使用Event这个数据结构来实现,它没有确定临界区的归属,也就是说,事件Event1锁上的临界区,其他临界区也可以去打开,这样我们可以去调控顺序

#include <Windows.h>
#include <iostream>
size_t g_count = 0;
HANDLE hEvent1;
HANDLE hEvent2;
HANDLE hEvent3;
CRITICAL_SECTION Critical_area{ 0 };
DWORD WINAPI ThreadProc1(
	_In_ LPVOID lpParameter
)
{
	WaitForSingleObject(hEvent1, -1);
	printf("线程一");
	SetEvent(hEvent2);
	return 0;
}
DWORD WINAPI ThreadProc2(
	_In_ LPVOID lpParameter
)
{
	WaitForSingleObject(hEvent2, -1);
	printf("线程二");
	SetEvent(hEvent3);
	return 0;
}
DWORD WINAPI ThreadProc3(
	_In_ LPVOID lpParameter
)
{
	WaitForSingleObject(hEvent3, -1);
	printf("线程三");
	return 0;
}
int main()
{
	hEvent1 = CreateEventW(NULL, FALSE, FALSE, L"one");
	hEvent2 = CreateEventW(NULL, FALSE, FALSE, L"two");
	hEvent3 = CreateEventW(NULL, FALSE, FALSE, L"three");
	SetEvent(hEvent1);
	InitializeCriticalSection(&Critical_area);
	HANDLE Tread1 = CreateThread(NULL, 0, ThreadProc1, NULL, 0, NULL);
	HANDLE Tread2 = CreateThread(NULL, 0, ThreadProc2, NULL, 0, NULL);
	HANDLE Tread3 = CreateThread(NULL, 0, ThreadProc3, NULL, 0, NULL);
	WaitForSingleObject(Tread1, -1);
	WaitForSingleObject(Tread2, -1);
	WaitForSingleObject(Tread3, -1);
	DeleteCriticalSection(&Critical_area);
	return 0;
}//这里我们通过Event事件通过控制信号状态使得,先让Event1事件先为信号状态,同步的过程执行完ThreadProc1,然后再setEvent为event2执行二,同理执行三

异步IO

同步IO,当我们读取一个文件时,一般情况下,线程是阻塞的,也就是说,需要当前的线程等待文件读取操作成功并且结束之后再进行下一步的操作(阻塞程序),这种叫做同步IO。

异步IO则是在用户读取文件的时候不会阻塞线程的进行,而是交给系统底层自动去处理读取文件,这样文件的读取就不会去阻塞线程的进行。

//异步读取文件
#include <Windows.h>
#include<iostream>
int main()
{
	HANDLE hFile = CreateFileW(L"game.txt", GENERIC_ALL, NULL, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	WCHAR buff[100]{ 0 };
	OVERLAPPED overlapped{ 0 };//lapped 重叠
	ReadFile(hFile, buff, 0x100, NULL, &overlapped);
	DWORD num_read;
	WaitForSingleObject(hFile, -1);
	GetOverlappedResult(hFile, &overlapped, &num_read, TRUE);
	printf("内容%s", buff);
	printf("长度%d", buff);
	return 0;
}

APC:

每一个线程都维护了一个APC队列,队列中的每一项都是一个函数,当线程处于闲暇状态时,线程会去遍历我们的APC队列,然后去调用所有函数,直到结束,再恢复执行。

//上面的代码虽然可以实现我们的异步IO,但是都没有真正的逃过临界区的等待,比如WaitForSingleObject(hFile, -1)....那我们应该怎么办才能真正的实现这一个操作呢?那就是通过回调函数,让函数直接告诉我们文件读取成功了,然后再进行下一步,所以windows有响应的API去实现我们的这一个情况
#include <Windows.h>
#include<iostream>
void WINAPI  lpOverLapped_completion_Proc(
	_In_    DWORD dwErrorCode,
	_In_    DWORD dwNumberOfBytesTransfered,
	_Inout_ LPOVERLAPPED lpOverlapped
)
{
	printf("dadadadad");
}
int main()
{
	HANDLE hFile = CreateFile(L"game.txt", GENERIC_ALL, NULL, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
	char buff[100]{ 0 };
	OVERLAPPED overapped{ 0 };
	//overapped.hEvent = CreateEventW(NULL, FALSE, FALSE, L"chen");//通过将hFile转为Event来实现判断文件的读取是否完成
	ReadFileEx(hFile, buff, 0x100, &overapped, lpOverLapped_completion_Proc);
	DWORD real_num;
	GetOverlappedResult(hFile, &overapped, &real_num, TRUE);
	printf("%s", buff);
	return 0;
}

标签:case,NULL,return,windows,int,线程,include
From: https://www.cnblogs.com/ovo-fisherman/p/18220671

相关文章

  • QGIS开发笔记(三):Windows安装版二次开发环境搭建(下):将QGis融入QtDemo,添加QGis并加载tif遥
    前言  使用QGis的目的是进行二次开发,或者说是融入我们的应用(无人车、无人船、无人机),本片描述搭建QGis二次基础开发环境,由于实在是太长了,进行了分篇:上半部分:主要是安装好后,使用QtCreator可以使用QGIs的apps下的Qt使用对应的编译器编译不带qgis的空工程。下半部分:在上半......
  • windows10安装centos7双系统详细教程
    Centos7系统使用了很长的时间,但是要不是在虚拟机环境下使用,要不就直接安装centos7系统,没有尝试过安装双系统使用,最近虚拟机运行起来电脑弄的很卡,索性就直接安装双系统使用,工作娱乐都能使用。下面开始介绍安装双系统的详细流程。1.安装环境硬件设备:戴尔7460笔记本,8G以上的U盘一个......
  • C++中以类的成员函数作为Windows callback函数需要设置成static函数
    在看代码时,发现很多CALLBACK函数,所以仔细研究了一下C++中的CALLBACK函数首先,我们来理解一下,什么是C++中的CALLBACK函数 =>凡是由你设计,但是由Windows操作系统调用的函数,我们把它统称为CALLBACK函数,这些函数都有一定的类型,以方便配合Windows的调用动作某些WindowsAPI函数会要......
  • Windows和Linux系统部署Docker(2)
    目录一、Linux系统部署docker前置环境:1.安装需要的软件包,yum-util提供yum-config-manager功能2.添加阿里云docker-ce 仓库3.安装docker软件包4.启动docker并设置开机自启5.查看版本:二、windows系统部署docker1.查看是否拥有bioss虚拟化功能2.开启虚拟化功能3.......
  • windows ollama 指定模型下载路径
    为Ollama指定模型的下载路径在Windows系统中,如果想为Ollama指定模型的下载路径,可以通过设置环境变量来实现。以下是详细的步骤:确定默认下载路径:默认情况下,Ollama的模型可能会下载到C:\Users\<用户名>\.ollama\models目录下。设置新的下载路径:如果想更改这个默认路径,需要设......
  • windows添加计划任务异常--问题总结
    首先确定.bat脚本双击可正常运行当使用windows添加计划任务后,运行无报错(看历史记录正常运行成功),但是脚本内容实际未成功可以看下以下内容:1.查看脚本名是否含有中文,改为全英文2.将执行用户改成SYSTEM3.脚本中添加切换到脚本文件夹的命令4.任务重添加脚本时添加脚本所在目录......
  • Windows 应用暂停技术汇总
    背景在特定场景下,一些进程运行单纯的浪费资源,但又不能杀掉进程,所以需要通过挂起的方式,暂停进程运行。以释放资源给关键进程运行。方法对比方法详解1.NtSuspendProcess通过直接调用NtSuspendProcess来对进程进行挂起,通过NtResumeProcess来恢复进程。此API是nt......
  • windows下载安装ipopt求解器 可用于pyomo调用
    方案一:采用官方编译的应用程序官方对windows下有已经编译好的应用程序,只需要下载下来,并将ipopt的应用程序所在文件夹路径添加到系统全局环境变量就可以了。这样在利用pyomo或者其他建模工具建模求解的时候就可以正常使用ipopt了。(但要注意防火墙或者杀毒软件可能会拦截需要设定......
  • Windows 11系统设置显示桌面图标方法分享
        随着Windows11操作系统的正式发布,许多用户纷纷升级,以体验其新颖的界面和改进的功能。然而,面对全新的用户界面和设置选项,即使是经验丰富的Windows用户也可能会遇到一些挑战。其中一个常见的问题就是如何在Windows11中设置显示桌面图标,这对于习惯了在桌面上组织文......
  • 将sublime text 3加入到windows右键功能中
    1.reg文件内容,编辑好之后,双击1.reg文件即可WindowsRegistryEditorVersion5.00[HKEY_CLASSES_ROOT\*\shell\SublimeText3]@="EditwithSublimeText3""Icon"="D:\\software\\sublime_text_build_4169_x64\\sublime_text.exe,0"[HKEY_CLASS......