windows API

207 阅读6分钟

1、Hellow word

#include<windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPSTR lpCmdLine, int nCmdShow)
{
	MessageBox(NULL, L"Hello World!", L"提示", MB_OK);
	return 0;
}

1647311096.png

2、创建窗口

e6f1a5cce18c7fba461a55a12994a6b.png

#include "framework.h"
#include "WindowsProject1.h"
#include<windows.h>


//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
	WPARAM wParam, LPARAM lParam)
{
	switch (Msg)
	{
	case  WM_DESTROY:
		PostQuitMessage(0);
		return   0;

	default:
		return  DefWindowProc(hWnd, Msg, wParam, lParam);
	}

	return 0;
}


int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
	LPSTR lpCmdLine, int  nShowCmd)
{
	//1.注册窗口类
	WNDCLASS  wnd;
	wnd.cbClsExtra = 0;
	wnd.cbWndExtra = 0;
	wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
	wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
	wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
	//wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
	wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
	wnd.lpszClassName = L"MrHuang";//窗口类名
	wnd.lpszMenuName = NULL;//菜单资源名称
	wnd.style = CS_HREDRAW;//窗口类、样式
	wnd.hInstance = hInstance;//实例句柄
	RegisterClass(&wnd);

	//创建窗口(返回之前发送WM_CREATE)
	HWND  hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
		WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, hInstance, NULL);

	//显示窗口
	ShowWindow(hWnd, nShowCmd);

	//更新窗口(发送WM_PAINT)
	UpdateWindow(hWnd);

	//消息循环(收到WM_QUIT消息退出)
	MSG  msg;
	BOOL  bRet = false;
	while (bRet = GetMessage(&msg, hWnd, 0, 0))
	{
		if (bRet == -1)
		{
			return -1;
		}
		TranslateMessage(&msg);//翻译消息
		DispatchMessage(&msg);//分发消息到窗口过程
	}

}

3551c278d881bc5f39e4e61c427b88d.png

3551c278d881bc5f39e4e61c427b88d.png

53756d89671011ca3ab801b55527925.png

73233eb00a4721074abe700cb935b59.png

ed80816347c1745b92d58d7f9ef5290.png

ed9d1c210f7e1e3590089a041360b9b.png

658ae563037ea43e893ec6c1b148978.png

3、线程和窗口、发送消息、消息分类

一个线程、消息队列可以加入连个窗口。


#include<windows.h>
#include<stdio.h>

//自定义消息
#define  WM_AAA    WM_USER+1

HWND  hWnd; 
HWND  hWnd2;


//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
	WPARAM wParam, LPARAM lParam)
{
	switch (Msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);//可以使GetMessage返回0    
		return 0; 

	case WM_AAA:
		MessageBoxA(NULL, "窗口过程:WM_AAA", "测试", MB_OK);
		return 0;
	}
	return DefWindowProc(hWnd, Msg, wParam, lParam);
}


int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
	LPSTR lpCmdLine, int  nShowCmd)
{
	//1.注册窗口类
	WNDCLASS  wnd;
	wnd.cbClsExtra = 0;
	wnd.cbWndExtra = 0;
	wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
	wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
	wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
												//wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
	wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
	wnd.lpszClassName = L"MrHuang";//窗口类名
	wnd.lpszMenuName = NULL;//菜单资源名称
	wnd.style = CS_HREDRAW;//窗口类、样式
	wnd.hInstance = hInstance;//实例句柄
	RegisterClass(&wnd);

	//创建窗口(返回之前发送WM_CREATE)
	hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
		WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, hInstance, NULL);

	//显示窗口
	ShowWindow(hWnd, nShowCmd);
	//更新窗口(发送WM_PAINT)
	UpdateWindow(hWnd);


	//创建窗口2(返回之前发送WM_CREATE)
	hWnd2 = CreateWindow(L"MrHuang", L"第二个窗口程序",
		WS_OVERLAPPEDWINDOW, 100, 500, 300, 300, NULL, NULL, hInstance, NULL);
	//显示窗口
	ShowWindow(hWnd2, nShowCmd);
	//更新窗口(发送WM_PAINT)
	UpdateWindow(hWnd2);

	 
	//消息循环(收到WM_QUIT消息退出)
	MSG  msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		//说明两个窗口公用一个消息循环和线程消息队列
		if (msg.message == WM_LBUTTONDOWN)
		{
			//char str[64];
			//sprintf(str,"窗口句柄:%p", msg.hwnd);
			//MessageBoxA(NULL, str,"测试", MB_OK);


			//SendMessage直接发给窗口过程函数,并且阻塞,除非被窗口过程处理才返回
			//SendMessage(hWnd, WM_AAA, 0, 0);

			//PostMessage放到线程消息队列里,并且立即返回,通过消息循环到窗口过程处理
			//PostMessage(hWnd, WM_AAA, 0, 0);

			//PostThreadMessage放到线程消息队列里,不进入窗口过程
			//PostThreadMessage(GetCurrentThreadId(), WM_AAA, 0, 0);
			
			//PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0);
			PostQuitMessage(0);//等价于上面的一行调用

			int  a = 100;
		}

		if (msg.message == WM_AAA)
		{
		    MessageBoxA(NULL, "消息循环:WM_AAA","测试", MB_OK); 
		}



		TranslateMessage(&msg);//翻译消息
		DispatchMessage(&msg);//分发消息到窗口过程
	}
}

961c8a1267c0b9a730de97a7fd2c001.png

ea83d5802a1f3acc5a9130b6c127ba0.png

4、windows 的创建和销毁

#include<windows.h>
#include<stdio.h>

//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
	WPARAM wParam, LPARAM lParam)
{
	switch (Msg)
	{
		///////////////////////////创建窗口///////////////////////////////
	case WM_NCCREATE:

		SetWindowTextA(hWnd, "改变标题");

		char str[64];
		sprintf(str, "WM_NCCREATE消息:%p!\n", hWnd);
		OutputDebugStringA(str);
		return  true;//这里必须返回true,否则不会发WM_CREATE消息,CreateWindow返回NULL

	case WM_CREATE:
	{
		CREATESTRUCT  *p = (CREATESTRUCT*)lParam; 
		sprintf(str, "WM_CREATE消息:%p!\n", hWnd); 

		OutputDebugStringA(str);
		return true;
	}

		///////////////////////////销毁窗口/////////////////////////////// 
	case WM_CLOSE:
		sprintf(str, "WM_CLOSE消息:%p!\n", hWnd);
		OutputDebugStringA(str); 
		DestroyWindow(hWnd);//销毁窗口,发出WM_DESTROY消息
		return 0;

	case WM_DESTROY: 
		sprintf(str, "WM_DESTROY消息:%p!\n", hWnd);
		OutputDebugStringA(str);
		PostQuitMessage(0);//可以使GetMessage返回0    
		return 0;
	case WM_NCDESTROY: 
		sprintf(str, "WM_NCDESTROY消息:%p!\n", hWnd);
		OutputDebugStringA(str);
		return 0;
	}
	return DefWindowProc(hWnd, Msg, wParam, lParam);
}


int  WINAPI   WinMain(HINSTANCE  hInstance, HINSTANCE  hPrevInstance,
	LPSTR lpCmdLine, int  nShowCmd)
{
	//1.注册窗口类
	WNDCLASS  wnd;
	wnd.cbClsExtra = 0;
	wnd.cbWndExtra = 0;
	wnd.hbrBackground = (HBRUSH)(GetStockObject(GRAY_BRUSH));//背景色
	wnd.hCursor = LoadCursor(NULL, IDC_ARROW);//光标
	wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);//图标
												//wnd.lpfnWndProc = DefWindowProc;//默认窗口过程函数,用于处理消息
	wnd.lpfnWndProc = MyWindowProc;//自定义的窗口过程函数
	wnd.lpszClassName = L"MrHuang";//窗口类名
	wnd.lpszMenuName = NULL;//菜单资源名称
	wnd.style = CS_HREDRAW | CS_DBLCLKS;//窗口类、样式
	wnd.hInstance = hInstance;//实例句柄
	RegisterClass(&wnd);

	//创建窗口(返回之前发送WM_CREATE)
	HWND  hWnd = CreateWindow(L"MrHuang", L"第一个窗口程序",
		WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, hInstance, NULL);
	char str[64];
	sprintf(str, "CreateWindow返回:%p!\n", hWnd);
	OutputDebugStringA(str); 

	//显示窗口
	ShowWindow(hWnd, nShowCmd);
	//更新窗口(发送WM_PAINT)
	UpdateWindow(hWnd);


	//消息循环(收到WM_QUIT消息退出)
	MSG  msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);//翻译消息
		DispatchMessage(&msg);//分发消息到窗口过程
	}
}

5、窗口更新消息

56111127fa16fa84be7ee0a52bc7b30.png

dc3d5b85a07316c72efe9e3712212bd.png

6、窗口鼠标键盘消息

7、控件

1、按钮

//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
	WPARAM wParam, LPARAM lParam)
{
	switch (Msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);//可以使GetMessage返回0    
		return 0;

	case  WM_CREATE:
	{       
		LPCREATESTRUCT   pcs = (LPCREATESTRUCT)lParam; 
		//创建位图按钮
		HWND   hBtn = CreateWindow(L"BuTtOn" /*不区分大小写*/, 
			L"XXX", WS_CHILD | WS_VISIBLE | BS_BITMAP,//指定为图片
			30, 30, 217, 46, hWnd, (HMENU)1000, pcs->hInstance, NULL);

		//LoadImage加载位图
		//HBITMAP  hBmp=(HBITMAP)LoadImage(NULL, L"C:\\Users\\35497\\Desktop\\code\\016\\Debug\\btn1.bmp",
		//	IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

		//采用LoadBitmap加载位图资源(必须在rc文件中定义)
		HBITMAP  hBmp= LoadBitmap(pcs->hInstance, MAKEINTRESOURCE(IDB_BITMAP1) );

		//向控件发送BM_SETIMAGE消息设置按钮图片
		LRESULT  ret=SendMessage(hBtn, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBmp);
		return 0;
	}

	case   WM_COMMAND:
	{
		WORD  id = LOWORD(wParam);
		WORD  code = HIWORD(wParam);
		HWND   hCtrl = (HWND)lParam;
		if (id == 1000 && code == BN_CLICKED)
		{
			MessageBox(hWnd, L"普通按钮被单击!", L"提示", MB_OK);
		} 
	}break; 

	default:
		break;
	}

	return DefWindowProc(hWnd, Msg, wParam, lParam);
}

2、静态文本


//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
	WPARAM wParam, LPARAM lParam)
{
	switch (Msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);//可以使GetMessage返回0    
		return 0;

	case  WM_CREATE:
	{
		LPCREATESTRUCT   pcs = (LPCREATESTRUCT)lParam; 

		//静态文本控件
	 HWND  hStatic=	CreateWindow(L"Static", L"这是一个静态文本", WS_CHILD | WS_VISIBLE |WS_BORDER|SS_BITMAP|SS_NOTIFY,
			30, 30,200, 30, hWnd, (HMENU)111, pcs->hInstance, NULL);
	 //更改窗口标题
	 SetWindowText(hWnd, L"新窗口标题");
	 //设置控件(子窗口)内容
	 SetWindowText(hStatic, L"更改后的内容!");


	 //加载位图
	HBITMAP  hBmp= LoadBitmap(pcs->hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
	
	//向控件发送STM_SETIMAGE消息设置静态控件的位图
	SendMessage(hStatic, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hBmp);
		return 0;
	}


	case   WM_COMMAND:
	{

		WORD  id = LOWORD(wParam);//控件ID
		WORD  code = HIWORD(wParam);//消息类型
		HWND   hCtrl = (HWND)lParam;//窗口句柄

		//父窗口接收到子控件发的消息
		if (id == 111  &&  code ==  STN_CLICKED)
		{
			MessageBox(NULL, L"静态文本被点击!", L"提示", MB_OK);
		}
	}
        break;
	default:
		break;
	}
	return DefWindowProc(hWnd, Msg, wParam, lParam);
}

df4f1032-4ea9-4f5a-b738-5eecd0315642.png

6249b840-c337-492d-b803-452621aa8d61.png

3、编辑框

//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
	WPARAM wParam, LPARAM lParam)
{
	switch (Msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);//可以使GetMessage返回0    
		return 0;

	case  WM_CREATE:
	{
		LPCREATESTRUCT   pcs = (LPCREATESTRUCT)lParam;
		 
		//创建编辑框控件
		HWND   hEdit=CreateWindow(L"ediT", L"这是一个编辑框", WS_CHILD | WS_VISIBLE | WS_VSCROLL |ES_MULTILINE|ES_AUTOVSCROLL|ES_NOHIDESEL,
			30, 30, 200, 100, hWnd, (HMENU)111, pcs->hInstance, NULL);

		//向编辑框发送选择字符串的消息
		SendMessage(hEdit, EM_SETSEL, 2, 6);

		//剪切刚刚选择的文字
		 //SendMessage(hEdit, WM_CUT, 0, 0); 

		 //撤销
		 //SendMessage(hEdit, EM_UNDO, 0, 0);

		return 0;
	} 

	case   WM_COMMAND:
	{

		WORD  id = LOWORD(wParam);//控件ID
		WORD  code = HIWORD(wParam);//消息类型
		HWND   hCtrl = (HWND)lParam;//窗口句柄

		 //父窗口接收到子控件发的消息
		if (id == 111 && code == EN_CHANGE)
		{
			//MessageBox(NULL, L"编辑框的文本被改变!", L"提示", MB_OK);

			TCHAR  buf[64] = {0};
			GetWindowText(hCtrl, buf, sizeof(buf));
			MessageBox(NULL,  buf , L"提示", MB_OK);
		}
	}break;
     default:
		break;
	}
	return DefWindowProc(hWnd, Msg, wParam, lParam);
}

f1e2f5cf-ed6e-4950-bf40-c5c8f0e54448.png

4、列表

//自定义的窗口过程
LRESULT  CALLBACK    MyWindowProc(HWND hWnd, UINT Msg,
	WPARAM wParam, LPARAM lParam)
{
	switch (Msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);//可以使GetMessage返回0    
		return 0;

	case  WM_CREATE:
	{
		LPCREATESTRUCT   pcs = (LPCREATESTRUCT)lParam;

		//创建列表框控件
		HWND   hListBox=CreateWindow(L"listBOX", L"XXX", WS_CHILD | WS_VISIBLE|LBS_SORT|LBS_NOTIFY,
			30, 30, 200, 100, hWnd, (HMENU)111, GetModuleHandle(NULL),  NULL);
 
		//向末尾添加选项
		SendMessage(hListBox, LB_ADDSTRING, 0,(LPARAM) L"B音乐");
		SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)L"A啤酒");
		SendMessage(hListBox, LB_ADDSTRING, 0, (LPARAM)L"C啤酒");
		//插入字符串
		SendMessage(hListBox, LB_INSERTSTRING, 1, (LPARAM)L"炸鸡");

		//选择其中一项,选择索引为2的,单选模式才有效
		SendMessage(hListBox, LB_SETCURSEL, 2, 0 );

		return 0;
	}
	case   WM_COMMAND:
	{
		WORD  id = LOWORD(wParam);//控件ID
		WORD  code = HIWORD(wParam);//消息类型
		HWND   hCtrl = (HWND)lParam;//窗口句柄

		 //父窗口接收到子控件发的消息
		if (id == 111 && code == LBN_SELCHANGE)//创建时需指定LBS_NOTIFY样式
		{
			// 获取当前选择的索引
			int  index=SendMessage(hCtrl, LB_GETCURSEL, 0,0);
			
			//获取索引对应的字符串 
			TCHAR  buf[64] = { 0 };
			SendMessage(hCtrl, LB_GETTEXT, index, (LPARAM)buf); 
			MessageBox(NULL, buf, L"提示", MB_OK);
		}

	}break;
	default:
		break;
	}
	return DefWindowProc(hWnd, Msg, wParam, lParam);
}

8c8252fd-8275-448e-973b-fa6d5bacc240.png

1a9ab0de-8fce-48b5-a51b-35b47c5c81a8.png