您的位置:首页 > 其它

【MFC】1.Windows程序内部运行原理

2016-07-15 20:55 281 查看

1.原理与内容

Windows应用程序,操作系统,计算机硬件之间的相互关系:



向下的箭头③表示应用程序可以通知操作系统执行某个具体的动作,如操作系统能够控制声卡发出声音,但它并不知道应该何时发出何种声音,需要应用程序告诉操作系统该发出什么样的声音。这个关系好比有个机器人能够完成行走的功能,但是,如果人们不告诉它往哪个方向上走,机器人是不会主动行走的。这里的机器人就是操作系统,人们就是应用程序。

向上的箭头④表示操作系统能够将输入设备的变化上传给应用程序。如用户在某个程序活动时按了一下键盘,操作系统马上能够感知到这一事件,并且能够知道用户按下的是哪一个键,操作系统并不决定对这一事件如何作出反应,而是将这一事件转交给应用程序,由应用程序决定如何对这一事件作出反应。好比有个蚊子叮了我们一口,我们的神经末梢(相当于操作系统)马上感知到这一事件,并传递给了我们的大脑(相当于应用程序),我们的大脑最终决定如何对这一事件作出反应,如将蚊子赶走,或是将蚊子拍死。对事件作出反应的过程就是消息响应。 
句柄(HANDLE),资源的标识。操作系统要管理和操作这些资源,都是通过句柄来找到对应的资源。按资源的类型,又可将句柄细分成图标句柄(HICON),光标句柄(HCURSOR),窗口句柄(HWND),应用程序实例句柄(HINSTANCE)等等各种类型的句柄。操作系统给每一个窗口指定的一个唯一的标识号即窗口句柄。 
创建一个完整的窗口需要经过下面四个操作步骤:
(1)设计一个窗口类;
(2)注册窗口类;
(3)创建窗口;
(4)显示及更新窗口。

2.API程序代码

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

//回调函数声明
LRESULT CALLBACK WindowProc(
HWND hwnd,      // handle to window
UINT uMsg,      // message identifier
WPARAM wParam,  // first message parameter
LPARAM lParam   // second message parameter
);
//操作系统调用,并给WINMAIN分配一个实例号,并传递参数
int WINAPI WinMain(
HINSTANCE hInstance,      // handle to current instance
HINSTANCE hPrevInstance,  // handle to previous instance
LPSTR lpCmdLine,          // pointer to command line
int nCmdShow              // show state of window  最大化显示 还是最小化显示
)
{
//第一步:设计窗口类
WNDCLASS wndcls;
wndcls.style = CS_HREDRAW | CS_VREDRAW;
// 水平和垂直重画,在窗口调整大小的时候告知
// 是否需要重画,如果填写两参数,表示重画,窗口内容将清除重画

wndcls.lpfnWndProc = WindowProc; // 回调函数
// 当应用程序收到某个窗口的消息,消息与窗口相关,需要调用一个函数作相应,
<span style="white-space:pre">		</span>   // 这些工作本来是有操作系统进行处理的,但是需要我们进行通知
// 不同的窗口有特定回调函数

wndcls.cbClsExtra = 0;  //类额外数据,内存空间称为类的附加内存
wndcls.cbWndExtra = 0;  //窗口附加内存
wndcls.hInstance  = hInstance;  //当前实例号,即利用操作系统传进来的形参hInstance进行复制

wndcls.hIcon = LoadIcon(NULL,IDI_ERROR ); //微软的标准图标第一个参数皆为NULL

wndcls.hCursor = LoadCursor(NULL,IDC_ARROW); //如用预定义光标,第一参数为NULL,IDC_CROSS

wndcls.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); //得到预定义的画刷,画笔等

wndcls.lpszMenuName = NULL; //窗口菜单名
wndcls.lpszClassName = "winmain"; //给本窗口类取个名字

//第二步:注册窗口类
RegisterClass(&wndcls); //向操作系统注册

//第三步:创建窗口
HWND hwnd; //句柄,标识/特征等,分配资源
hwnd = CreateWindow("winmain",  //操作系统认识的名字
<span style="white-space:pre">	</span>"第一个实验!", //标题栏的名字
WS_OVERLAPPEDWINDOW /* &~WS_MAXIMIZEBOX */,
0,//CW_USEDEFAULT,//窗口显示的时候,采用操作系统默认为位置及大小
0,//CW_USEDEFAULT,
200,//CW_USEDEFAULT,
200,//CW_USEDEFAULT, /*自主设定0,0,100,200*/
NULL,       //父窗口的句柄
NULL,      //菜单的句柄
hInstance, //当前的实例,操作系统传的值
NULL);

//第四步:显示窗口
ShowWindow(hwnd,SW_SHOWNORMAL); //显示哪一个窗口???

//第五步:更新窗口,可有可无
UpdateWindow(hwnd);

MSG msg;
//每次循环从消息队列中取出一条消息进行处理
while(GetMessage(&msg,NULL,0,0)) //NULL  调用线程任意窗口的消息
{
//该语句将类似于WM_KeyDown和WM_KeyUp转换生成新WM_CHAR投递给系统处理
TranslateMessage(&msg);
//将消息投递出去给操作系统,操作系统会自动调用回调函数处理
DispatchMessage(&msg);
}
return 0;
}

LRESULT CALLBACK WindowProc(
HWND hwnd,      // handle to window
UINT uMsg,      // message identifier
WPARAM wParam,  // first message parameter
LPARAM lParam   // second message parameter
)
{
HDC hdc;
switch(uMsg) {
case WM_PAINT:
PAINTSTRUCT ps;
hdc=BeginPaint(hwnd,&ps);
TextOut(hdc,0,10,"hello world!",strlen("hello world!"));
EndPaint(hwnd,&ps);
break;
case WM_CHAR:
char szChar[20];
sprintf(szChar,"char is %d",wParam);
MessageBox(hwnd,szChar,"Warnning!",MB_OK);
case WM_LBUTTONDOWN:
hdc=GetDC(hwnd); //得到当前窗口的上下文句柄
TextOut(hdc,0,50,"沈春旭作品",strlen("沈春旭作品"));
ReleaseDC(hwnd,hdc);
break;
case WM_CLOSE:
if(IDOK==MessageBox(hwnd,"确认要退出嘛?","Warning!",MB_OK))
{
//销毁窗口,但进程中还是保留的,该函数直接抛出WM_DESTROY消息
DestroyWindow(hwnd);
}
break;
case WM_DESTROY:
PostQuitMessage(0); //终止消息循环,并抛出WM_QUIT消息,从而导致上面的消息循环退出
default:
//对于代码中没有涉及到的消息,由提交给系统处理,此句一定要加,否则窗口不会出现
return DefWindowProc(hwnd,uMsg,wParam,lParam);
}
return 0;
}

3.执行结果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: