基本概念

SDK

软件开发工具包(Software Development Kit),一般都是一些被软件工程师用于为特定的软件包、软件框架、硬件平台、操作系统等建立应用软件的开发工具的集合。 

API

Windows操作系统提供给应用程序编程的接口(Application Programming Interface)。

Windows应用程序API函数是通过C语言实现的,所有主要的 Windows 函数都在 Windows.h 头文件中进行了声明。Windows 操作系统提供了 1000 多种 API函数。

窗口和句柄

窗口是屏幕上的一块矩形区域,是 Windows 应用程序与用户进行交互的接口。利用窗口可以接收用户的输入、以及显示输出。

在 Windows 应用程序中, 窗口是通过窗口句柄( HWND) 来标识的。

句柄( HANDLE) 是 Windows 程序中一个重要的概念, 在 Windows 程序中, 有各种各样的资源( 窗口、 图标、光标,画刷等), 系统在创建这些资源时会为它们分配内存, 并返回标识这些资源的标识号, 即句柄。 

消息和消息队列

Windows 程序设计是一种完全不同于传统的 DOS 方式的程序设计方法。它是一种事件驱动方式的程序设计模式,主要是基于消息的

每一个 Windows 应用程序开始执行后, 系统都会为该程序创建一个消息队列, 这个消息队列用来存放该程序创建的窗口的消息。
例如,当用户在窗口中画图的时候,按下鼠标左键,此时,操作系统会感知到这一事件,于是将这个事件包装成一个消息,投递到应用程序的消息队列中,等待应用程序的处理。

然后应用程序通过一个消息循环不断地从消息队列中取出消息,并进行响应。

在这个处理过程中,操作系统也会给应用程序“ 发送消息”。所谓“ 发送消息”,实际上是操作系统调用程序中一个专门负责处理消息的函数,这个函数称为窗口过程

 

 WinMain函数

当Windows操作系统启动一个程序时,它调用的就是该程序的WinMain函数( 实际是由插入到可执行文件中的启动代码调用的)。

WinMain是Windows程序的入口点函数,与DOS程序的入口点函数main的作用相同,当WinMain 函数结束或返回时,Windows应用程序结束

Windows 编程模型

一个完整的Win32程序(#include <windows.h>),该程序实现的功能是创建一个窗口,并在该窗口中响应键盘及鼠标消息,程序的实现步骤为:

  1. WinMain函数的定义
  2. 创建一个窗口
  3. 进行消息循环
  4. 编写窗口过程函数

 

项目的创建

 

 

 

#include <windows.h>

//6.处理窗口过程
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)//消息所属窗口句柄,具体消息名称,键盘附件消息,鼠标附加消息
{
	switch (uMsg)
	{
	case WM_CLOSE:
		//所有xxxWindow为结尾的方法 ,都不会进入到消息队列中,而是直接执行
		DestroyWindow(hwnd); //DestroyWindow 发送另一个消息 WM_DESTROY
		break;
	case  WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_LBUTTONDOWN: //鼠标左键按下
	{
		int xPos = LOWORD(lParam);
		int yPos = HIWORD(lParam);

		char buf[1024];
		wsprintf(buf, TEXT("x = %d,y = %d"), xPos, yPos);

		MessageBox(hwnd, buf, 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 world"), strlen("Hello world"));

		EndPaint(hwnd, &ps);
	}

	break;
	}
	
	return DefWindowProc(hwnd,uMsg,wParam,lParam);
}



//WINAPI代表__stdcall 参数传递顺序:从右到左,由此入栈,并且在函数返回前 清空堆栈
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)//应用程序实例句柄;上一个应用程序句柄,在Win32情况下,参数一般为NULL,不起作用;vhar * argv[];显示命令,最大化,最小化,正常
{
	//1.设计窗口
	//2.注册窗口
	//3.创建窗口
	//4.显示和更新
	//5.通过循环取消息
	//6.窗口过程


	//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);
	wc.hInstance = hInstance;//应用程序实例句柄,传入WinMain中的形参即可
	wc.lpfnWndProc=WindowProc; //回调函数,窗口过程
	wc.lpszClassName = TEXT("Win");
	wc.lpszMenuName = NULL;
	wc.style = 0;

	//2.注册窗口
	RegisterClass(&wc);

	//3.创建窗口
	/*
	lpClassName,类名
	lpWindowName,标题名
	dwStyle,WS_OVERLAPPEDWINDOW
	x, y,显示坐标CW_USEDEFAULT
	nWidth, nHeight, 宽高
	hWndParent, 父窗口 NULL
	hMenu, 菜单,null
	hInstance, 实例句柄
	lpParam附加值,鼠标附加值 NULL
	*/
	HWND hwnd=CreateWindow(wc.lpszClassName, TEXT("WINDOWS"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);

	//4.显示和更新

	ShowWindow(hwnd, SW_SHOWNORMAL);

	//5.通过循环区消息
	MSG msg;
	/*
	HWND        hwnd;主窗口
	UINT        message;具体消息名称
	WPARAM      wParam;附加消息,键盘消息
	LPARAM      lParam;附件消息,鼠标消息
	DWORD       time;消息产生时间
	POINT       pt;附加消息,鼠标消息,x, y
	*/

	while (1)
	{
		/*
		_Out_ LPMSG lpMsg,消息
	_In_opt_ HWND hWnd,捕获窗口,NULL代表所有窗口
	_In_ UINT wMsgFilterMin,最小和最大过滤消息 一般填零
	_In_ UINT wMsgFilterMax);
		*/

		if (GetMessage(&msg, NULL, 0, 0) == FALSE)
		{
			break;
		}

		TranslateMessage(&msg);

		DispatchMessage(&msg);

	}

	

	return 0;
}

 

 

 

 

 

 

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐