Windows程序内部运行机制

API与SDK

应用程序编程接口(Application Programming Interface)

我们在写C程序的时候会调用各种库函数来辅助完成某些功能,例如printf,这就是API,Windows操作系统提供了1000多种API函数。

软件开发包(Software Development Kit)

假如我们要开发呼叫中心,在购买语音卡的同时,厂商就会提供语音卡的SDK开发包,以方便我们对语音卡的编程操作,这个开发包通常会包含语音卡的API函数库、帮助文档、使用手册、辅助工具等资源。

API和SDK是一种广泛使用的专业术语,并没有专指某一种特定的API和SDK。

窗口与句柄

一个Windows应用程序至少有一个窗口,称为主窗口,接收用户输入,显示输出。窗口分为客户区和非客户区,客户区中显示文字或绘制图形,非客户区指标题栏、菜单栏、系统菜单、最小化框、最大化框等,他们由Windows系统来管理。应用程序主要管理客户区的外观和操作。

在Windows应用程序中,窗口时通过窗口句柄(HWND)来标识的。我们要对某个窗口进行操作,首先要得到这个窗口的句柄。

句柄(HANDLE),在Windows程序中,系统在创建窗口、图标、光标等资源的时候会为他们分配内存,并返回标识这些资源的标识号,即句柄。

窗口句柄(HWND)
图标句柄(HICON)
光标句柄(HCURSOR)
画刷句柄(HBRUSH)

消息与消息队列

Windows程序设计是一种事件驱动方式的程序设计模式,主要是基于消息的。例如,当用户在画图的时候,按下鼠标左键,此时,操作系统会感知到这一事件,于是将这个事件包装成一个消息,投递到应用程序的消息队列中,然后应用程序从消息队列中取出消息并进行响应。在这个处理过程中,操作系统也会给应用程序“发送消息”,即操作系统调用程序中一个专门负责处理消息的函数,这个函数称为窗口过程。

typedef struct tagMSG {     // msg  
   HWND hwnd;//标识窗口
   UINT message;//消息标识符
   WPARAM wParam;//附加消息 unsigned int 
   LPARAM lParam;//附加消息 long
   DWORD time;//消息投递到消息队列的时间
   POINT pt;//鼠标的当前位置
} MSG;

每一个Windows应用程序在开始执行后,系统都会为该程序创建一个消息队列,这个消息队列用来存放该程序创建的窗口消息。

Windows将产生的消息依次放入消息队列中,而应用程序则通过一个消息循环不断的从消息队列中取出消息,并进行响应。

进队的消息将由系统放入应用程序的消息队列中,由应用程序取出并发送。

不进队的消息在系统调用窗口过程时直接发送给窗口

WinMain函数

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

WinMain函数的定义

1.创建窗口
  1. 设计一个窗口类
  2. 注册窗口类
  3. 创建窗口
  4. 显示及更新窗口
2.消息循环

窗口过程函数

用于处理发送给窗口的消息。

程序实例


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

LRESULT CALLBACK WinMyProc(
	HWND hwnd,//窗口句柄
	UINT uMsg,//消息标识符
	WPARAM wParam,//消息的附加信息wParam 类型为unsigned int
	LPARAM lParam//消息的附加信息lParam 类型为long
);
int WINAPI WinMain(
	HINSTANCE hInstance,//程序当前运行的实例的句柄,这是一个数值
	HINSTANCE hPrevInstance,//当前实例的前一个实例的句柄,在Win32环境下,这个参数总为NULL
	LPSTR lpCmdLine,//指定传递给应用程序的命令行参数,是一个以空终止的字符串
	int nCmdLine//指定程序的窗口应该如何显示,最大化、最小化、隐藏等,一般不需要去理会
)
{
	//设计一个窗口类
	WNDCLASS wndcls;
	wndcls.cbClsExtra = 0;//类附加内存
	wndcls.cbWndExtra = 0;//窗口附加内存
	wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//指定窗口类的背景画刷句柄
	wndcls.hCursor = LoadCursor(NULL, IDC_CROSS);//光标句柄,NULL表示使用系统默认光标
	wndcls.hIcon = LoadIcon(NULL, IDI_ERROR);//指定窗口类的图标句柄,NULL表示使用系统默认图标
	wndcls.hInstance = hInstance;//指定包含窗口过程的程序的实例句柄
	wndcls.lpfnWndProc = WinMyProc;//函数指针,指向窗口过程函数
	wndcls.lpszClassName = "my2019";//指定窗口类的名称
	wndcls.lpszMenuName = NULL;//指定菜单资源的名字,是一个以空终止的字符串,NULL表示没有默认菜单
	wndcls.style = CS_HREDRAW | CS_VREDRAW;//当水平或垂直方向宽度或高度发生变化时,将重新绘制窗口

	//注册窗口
	RegisterClass(&wndcls);

	//创建窗口,定义一个变量用来保存成功创建窗口后返回的句柄
	HWND hwnd;
	hwnd = CreateWindow(
		"my2019",//lpszClassName,窗口类的名称
		"first",//窗口的名字,如果窗口样式指定了标题栏,将显示在标题栏
		WS_OVERLAPPEDWINDOW,//窗口的样式
		0,//窗口左上角x坐标
		0,//窗口左上角y坐标
		600,//窗口宽度
		400,//窗口高度
		NULL,//父窗口句柄
		NULL,//父窗口句柄
		hInstance,//窗口所属的应用程序实例的句柄
		NULL//作为WM_CREATE消息的附加参数lParam传入的数据指针,多数窗口为NULL,创建多文档时lParam需指向
	);

		//显示及刷新窗口
		ShowWindow(hwnd,SW_SHOWNORMAL);
		UpdateWindow(hwnd);

		//定义消息结构体
		MSG msg;
		while(GetMessage(&msg, NULL, 0, 0))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		return msg.wParam;
}

//编写窗口过程函数
LRESULT CALLBACK WinMyProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_CHAR:
		char szChar[20];
		sprintf_s(szChar, sizeof(szChar), "char code is %d", wParam);
		MessageBox(hwnd, szChar, "char", 0);
		break;
	case WM_LBUTTONDOWN:
		MessageBox(hwnd, "mouse clicked", "message", 0);
		HDC hdc;
		hdc = GetDC(hwnd);
		TextOut(hdc, 0, 50, "程序员之家", strlen("程序员之家"));
		ReleaseDC(hwnd, hdc);
		break;
	case WM_PAINT:
		HDC hDC;
		PAINTSTRUCT ps;
		hDC = BeginPaint(hwnd, &ps);
		TextOut(hDC, 0, 0, "WM_PAINT", strlen("WM_PAINT"));
		EndPaint(hwnd, &ps);
		break;
	case WM_CLOSE:
		if (IDYES == MessageBox(hwnd, "是否真的结束?", "message", MB_YESNO))
		{
			DestroyWindow(hwnd);
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, uMsg, wParam, lParam);
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值