我是靠谱客的博主 现代棒棒糖,最近开发中收集的这篇文章主要介绍(孙鑫C++)windows 程序内部运行原理,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一.Windows程序内部运行原理
1.关于消息和消息队列
系统将每个事件都包装成一个称为消息的结构体MSG来传递给应用程序,MSG结构定义如下:
typedef struct tagMsg{
HWND hwnd;
UINT message;
//消息种类,以WM_开头的一些消息
WPARAM wParam;
//这两个是消息的补充
LPARAM lParam;
DWORD time;
//消息被投递post的时间
POINT pt;
//这是一个点数据(结构体,有x、y),记录投递消息时光标cursor的屏幕坐标coordinate
}MSG;
2.windows程序的入口WinMain函数
int WINAPI WinMain(
HINSTANCE hInstance,
// handle to current instance
当前运行的实例句柄
HINSTANCE hPrevInstance,
// handle to previous instance 先前运行的实例句柄
LPSTR lpCmdLine,
// command line;lp开头(long pointer) 表示指针,str表示字符串;这里是命令行参数
int nCmdShow
// show state窗口显示状态(最大化、最小化……)
);
(可以在运行里面输入notepad.exe 1.txt传递一个参数)
3.窗口的创建
需要经过下面四个操作步骤:
·设计一个窗口类
·注册窗口类
·创建窗口
·显示及更新窗口
1)
typedef struct _WNDCLASS {
UINT
style;
//可以设为CS_HREDRAW,即窗口水平坐标变化时窗口全部重画
WNDPROC	lpfnWndProc; //回调函数(由系统调用),直接将函数名赋给此参数(即函数指针)
int
cbClsExtra;
//为窗口类分配附加内存空间(所有属于这个窗口类的窗口共享)
int
cbWndExtra;
//窗口实例附加内存空间
HANDLE
hInstance;
HICON
hIcon;
//用LoadIcon赋值
HCURSOR
hCursor;
//用LoadCursor
HBRUSH
hbrBackground;
//画刷背景,这里用GetStockObject()获取,它参数是系统带的。如:=(HBRUSH)GetStockObject(BLACK_BRUSH),这里有强制类型转换
LPCTSTR
lpszMenuName;
//CT=constant……菜单名
LPCTSTR
lpszClassName;
//窗口类名
} WNDCLASS;
经常会遇到一类变量,其每一位bit都对应某一种属性(1有0无),系统定义了一些常量(宏定义),只有一位为1,其余为0。若要同时用这几种特性,则用或运算|;要去掉某一特征,用取反~之后再进行与运算&即实现。(or有;and not取消,类似VB)
HICON
LoadIcon(
HINSTANCE hInstance,
//若加载标准图标则为NULL(系统自带的,如IDI_APPLICATION)
LPCTSTR lpIconName
);
HGDIOBJ GetStockObject(
__in
int fnObject
);
2)
然后用RegisterClass(&wndcls)注册窗口类
ATOM RegisterClass(
CONST WNDCLASS *lpWndClass
);
3)
再用hwnd=CreateWindow()创建窗口
HWND CreateWindow(
LPCTSTR lpClassName,
//窗口类名,必须是先前设计的
LPCTSTR lpWindowName, //窗口名字
DWORD dwStyle,//窗口样式window styles,如WS_OVERLAPPEDWINDOW,若想去掉最大化按钮(加个&~WS_MAXIMIZEBOX)
int x,
//窗口初始位置,可设置为CW_USEDEFAULT,这样就忽略y的值了
int y,
int nWidth,
//宽度,也可用CW_USEDEFAULT
int nHeight,
HWND hWndParent,
//父窗口句柄,没有则为NULL
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
//
作为WM_CREATE消息的参数lParam
);
4)显示窗口ShowWindow
BOOL ShowWindow(
HWND hWnd,
int nCmdShow
//窗口状态,如SW_SHOWMAXIMIZED
);
之后用UpdateWindow(hwnd)刷新窗口,这里可有可无
4.获取消息GetMessage
BOOL GetMessage(
//获取到WM_QUIT消息时,返回值为0;其他为非0值
LPMSG lpMsg,
HWND hWnd,
//为NULL时表示属于当前线程的所有消息
UINT wMsgFilterMin,
//最低的消息值
UINT wMsgFilterMax
//最高消息值
);
消息循环:
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
//将按键消息(KEYDOWN/KEYUP和对应字符的扫描码)转换成WM_CHAR消息
DispatchMessage(&msg);
//派送消息,将消息发送给窗口程序
}
return 0;
5.窗口程序:
LRESULT CALLBACK WindowProc(
//窗口名可随意取,这里CALLBACK其实就是__stdcall(标准调用格式,宏定义的)
HWND hwnd,
// handle to window
UINT uMsg,
// message identifier
WPARAM wParam,
// first message parameter
LPARAM lParam
// second message parameter
)
{
switch(uMsg)
{
case WM_CHAR:
//按下按键
char szChar[20];
sprintf(szChar,"char is %d",wParam);
//格式化文本到一个内存区(buffer)
MessageBox(hwnd,szChar,"weixin",0);
break;
case WM_LBUTTONDOWN:
MessageBox(hwnd,"mouse clicked","weixin",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,"维新培训",strlen("维新培训"));
EndPaint(hwnd,&ps);
break;
case WM_CLOSE:
if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO))
{
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
6.所用其他函数分析:
1)int MessageBox(
HWND hWnd,
LPCTSTR lpText,
//显示的文本(存放到一个字符数组,或直接用“”括起输出字符)
LPCTSTR lpCaption,
//标题
UINT uType
// 样式,如MB_OK=0(方便就写0)/MB_OKCANCEL
);
返回值有:IDOK,IDNO,IDYES……
2)画图、输出
先用GetDC:
HDC GetDC(
__in
HWND hWnd
//窗口句柄,若为NULL则返回整个屏幕的DC(device context设备上下文、环境)
);
再用TextOut输出文本:
BOOL TextOut(
__in
HDC hdc,
__in
int nXStart,
//这两者是文本输出的开始坐标
__in
int nYStart,
__in
LPCTSTR lpString,
//输出的文本
__in
int cbString
//输出的字符个数
);
注意最后要释放DC:用ReleaseDC
int ReleaseDC(
__in
HWND hWnd,
__in
HDC hDC
);
3)WM_PAINT消息(窗口加载、窗口移动时窗口要重绘)
先用	HDC hdc;PAINTSTRUCT ps;
hdc=BeginPaint(hwnd,&ps) //在重绘时获取DC
HDC BeginPaint(
__in
HWND hwnd,
__out
LPPAINTSTRUCT lpPaint
//这里是PAINTSTRUCT变量的指针,如&ps
);
使用(如TextOut(hdc,0,0,"维新培训",strlen("维新培训")))完之后,要用EndPaint释放DC
BOOL EndPaint(
__in
HWND hWnd,
__in
const PAINTSTRUCT *lpPaint
);
这里BeginPaint和EndPaint只能用WM_PAINT消息中
4)WM_CLOSE(窗口即将关闭时的消息)
if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO))
{
DestroyWindow(hwnd);
}
经验:在条件测试的时候,一般把常量(IDYES)写在前面,不容易出错
BOOL DestroyWindow(
//销毁窗口,程序还没退出,它会发送WM_DESTROY消息和WM_NCDESTROY消息
HWND hWnd
);
5)WM_DESTROY
//窗口销毁
void PostQuitMessage(
//投递一个WM_QUIT消息给这个线程的消息队列
int nExitCode
//它用来当做WM_QUIT消息的wParam
);
6)其它消息:
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
//默认的窗口程序
7.用VC编写:
1)选择win32 application工程(选择空工程)
2)添加C++源文件
3)包含头文件:#include "windows.h"	#include "stdio.h"
4) 写WinMain函数,可查msdn
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
);
5)在WinMain函数中设计一个窗口类
{
WNDCLASS wndcls;
wndcls.cbClsExtra=0;
wndcls.cbWndExtra=0;
wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wndcls.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wndcls.hCursor=LoadCursor(NULL,IDC_ARROW);
wndcls.hInstance=hInstance;
wndcls.lpfnWndProc=WinSunProc;
wndcls.lpszClassName="first";
wndcls.lpszMenuName=NULL
wndcls.style=CS_HREDRAW | CS_VREDRAW;
}
6)在WinMain中注册窗口类
RegisterClass(&wndcls);
7)创建窗口
HWND hwnd;
hwnd=CreateWindow("first","我第一个窗口",WS_OVERLAPPEDWINDOW,USER_DEFAULT,0,0,USER_DEFAULT,NULL,NULL,hInstance,NULL);
8)显示窗口
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
9)消息循环
MSG msg;
while(GetMessage(&msg,NULL,0,0)
//获取到WM_QUIT消息时才退出循环,注意这里是NULL表示接受所有消息
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0; //winmain返回0
10)窗口过程
LRESULT CALLBACK WindowProc(
//注意改名WinSunProc,和申明
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch(uMsg)
{
case WM_CHAR:
break;
case WM_LBUTTONDOWN:
break;
case WM_PAINT:
break;
case WM_CLOSE:
break;
case WM_DESTROY:
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}
11)编写具体过程:
1.WM_CHAR:
char szChar[20];
sprintf(szChar,"asc is %d",wParam);
MessageBox(hwnd,szChar,"MyFirst",0);
2.WM_PAINT:
PAINTSTRUCT ps;
HDC hdc;
hdc=BeginPaint(hwnd,&ps);
TextOut(hdc,0,0,"painting...",strlen("painting..."));
EndPaint(hwnd,&ps);
break;
3.WM_CLOSE:
if(IDYES==MessageBox(hwnd,"exit?","MyFirst",MB_YESNO))
{
DestroyWindow(hwnd);
}
break;
4.WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;

最后

以上就是现代棒棒糖为你收集整理的(孙鑫C++)windows 程序内部运行原理的全部内容,希望文章能够帮你解决(孙鑫C++)windows 程序内部运行原理所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部