概述
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.创建窗口
- 设计一个窗口类
- 注册窗口类
- 创建窗口
- 显示及更新窗口
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;
}
最后
以上就是外向钢笔为你收集整理的Windows程序内部运行机制的全部内容,希望文章能够帮你解决Windows程序内部运行机制所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复