• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > Windows程序内部运行机制实例详解

Windows程序内部运行机制实例详解

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了windows7使用详解,windows api开发详解,windows消息机制详解,windows注册表详解,windows7注册表详解等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

本文以孙鑫老师VC++教程中的程序为基础,详细讲解了Windows程序内部运行机制,相信可以帮助大家更好的理解Windows程序运行原理及相应的VC++程序设计。具体内容如下:

创建一个Win32应用程序步骤:

1、编写WinMain函数;

2、创建窗口(步骤如下):

 a、设计(一个)窗口类(WNDCLASS)

 b、注册(该)窗口类。

 c、创建窗口。

 d、显示并更新窗口。

3、编写消息循环。

4、编写窗口过程函数。

//WinMain.cpp
#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK WinAzeProc(
   HWND hwnd,   // handle to window
   UINT uMsg,   // message identifier
   WPARAM wParam, // first message parameter
   LPARAM lParam  // second message parameter
   );

int WINAPI WinMain(
          HINSTANCE hInstance,   // handle to current instance
          HINSTANCE hPrevInstance, // handle to previous instance
          LPSTR lpCmdLine,     // command line
          int nCmdShow       // show state
          )
{
  //设计一个窗口类
  WNDCLASS wndcls;
  wndcls.cbClsExtra = 0;
  wndcls.cbWndExtra = 0;
  wndcls.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
  wndcls.hCursor = LoadCursor(NULL, IDC_CROSS);
  wndcls.hIcon = LoadIcon(NULL, IDI_ERROR);
  wndcls.hInstance = hInstance;  //应用程序实例句柄由WinMain函数传进来
  wndcls.lpfnWndProc = WinAzeProc;
  wndcls.lpszClassName = "aze_003";
  wndcls.lpszMenuName = NULL;
  wndcls.style = CS_HREDRAW | CS_VREDRAW;

  RegisterClass(&wndcls);  //注册窗口类
  
  //创建窗口,定义一个变量用来保存成功创建后返回的句柄
  HWND hwnd;  
  hwnd = CreateWindow("aze_003", "first Application", WS_OVERLAPPEDWINDOW, 0, 0, 600, 500, NULL, NULL,hInstance, NULL);

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

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

//编写窗口过程函数
LRESULT CALLBACK WinAzeProc(
   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 code is %d", wParam);
    MessageBox(hwnd, szChar, "char", 0);
    break;
  case WM_LBUTTONDOWN:
    MessageBox(hwnd, "mouse clicked", "message", 0);
    HDC hdc;
    hdc = GetDC(hwnd);    //不能在响应WM_PAINT消息时调用
    TextOut( hdc, 0, 50, "程序员之家!",strlen("程序员之家!") );
    ReleaseDC(hwnd, hdc);
    break;
  case WM_PAINT:
    HDC hDC;
    PAINTSTRUCT ps;
    hDC = BeginPaint(hwnd, &ps);  //BeginPaint只能在响应WM_PAINT消息是调用
    TextOut(hDC, 0, 0, "http://www.sunxin.org", strlen("http://www.sunxin.org"));
    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;
}

</div>

程序运行后显示界面如下:

窗口分为客户区(是窗口的一部分)与非客户区。

标题栏、菜单栏、系统菜单、最小(大)化框、可调边框统称为窗口的非客户区,由Windows系统管理;应用程序主要管理客户区的外观及操作(显示文字、绘制图形)。

对话框、消息框也是一种窗口;对话框上还包括许多子窗口:按钮、单选按钮、复选框、组狂、文本编辑框等。

2、窗口与句柄:

在Windows应用程序中,窗口是通过窗口句柄(HWND)来标识的;要对某个窗口进行操作,就必须要得到这个窗口的句柄。

句柄是Windows程序中一个重要的概念(图标句柄(HICON)、光标句柄(HCURSOR)、画刷句柄(HBRUSH))。

3、消息与消息队列:

Windows程序设计模式是一种事件驱动方式的程序设计模式,主要是基于消息的。(当系统感知到一事件时(如点击鼠标),系统会将这个事件包装成一个消息,投递到应用程序的消息队列中,然后应用程序从消息队列中取出消息并进行响应。在这个处理过程中,操作系统也会给应用程序“发送消息”。“发送消息”:实际指:操作系统调用程序中一个负责处理消息的窗口过程函数)

(1)消息:Windows中,消息由MSG结构体表示,如下: 

//The MSG structure contains message information from a thread's message queue. 

typedef struct tagMSG {
 HWND  hwnd;     //消息所属的窗口,消息都是与窗口相关联的
 UINT  message;   //the message identifier
 WPARAM wParam;    //指定消息的附加消息
 LPARAM lParam;    //指定消息的附加消息
 DWORD time;     //消息投递到队列中的时间
 POINT pt;      //鼠标的当前位置
} MSG, *PMSG;

</div>

Windows中,消息是由一个个数值表示的;Windows将消息对应的数值定义为WM_XXX宏(WM:Window Message)的形式,XXX对应某种消息的英文拼写的大写形式。如:WM_LBUTTONDOWN:鼠标左键按下消息、WM_KEYDOWN:键盘按下消息、WM_CHAR:字符消息···

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

(3)进队消息 与 不进队消息:

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

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

      两者最终都是有系统调用窗口过程函数对消息进行处理。

4、WinMain函数

(一)MSDN上的WinMain函数定义如下(备有详尽的注释):

//The WinMain function is called by the system as the initial entry point for a Windows-based application. 

int WINAPI WinMain(
 HINSTANCE hInstance,   // handle to current instance当前窗口句柄
 HINSTANCE hPrevInstance, // handle to previous instance前一个打开的窗口句柄
 LPSTR lpCmdLine,     // command line 指定传递给应用程序的*命令行*参数
 int nCmdShow       // show state 指定窗口应该如何显示,如:最大(小)化、隐藏等
);

</div>

(二)窗口类的结构体的定义:

(1)本文程序中对应代码如下:

typedef struct _WNDCLASS { 
  UINT    style;    //指定*这一类型*窗口的样式,如:CS_HREDRAW、CS_VREDRAW、CS_NOCLOSE、CS_DBLCLKS
  WNDPROC  lpfnWndProc;   //函数指针,指向窗口过程函数(窗口过程函数是一回调函数)
  int    cbClsExtra;   //一般为0
  int    cbWndExtra;   //同上
  HINSTANCE hInstance;   //指定包含窗口过程的程序的实例句柄
  HICON   hIcon;     //指定窗口类的图标句柄
  HCURSOR  hCursor;   //指定窗口类的光标句柄
  HBRUSH   hbrBackground;   //指定窗口类的背景画刷句柄;当窗口发生重绘值,系统使用这里指定的画刷来查处窗口的背景
  LPCTSTR  lpszMenuName;   //指定菜单资源的名字 **菜单并不是一个窗口**
  LPCTSTR  lpszClassName;   //指定窗口类的名字
} WNDCLASS, *PWNDCLASS;

</div>

回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时有另一方调用的,用于该事件或条件进行响应。

回调函数的实现机制是:

    ①定义一个回调函数。

    ②提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者。

    ③当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。

针对Windows的消息处理机制,窗口过程函数被调用的过程如下:

    ①在设计窗口类的时候,将窗口过程函数的地址赋值给lpfnWndProc成员变量;

    ②调用RegisterClass(&wndclass)注册窗口类,那么系统就有了我们所编写的窗口过程函数的地址。

    ③

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • Windows程序内部运行机制实例详解

相关文章

  • 2017-05-28VC中Tab control控件的用法详细解析
  • 2017-05-28简单分析C语言中指针数组与数组指针的区别
  • 2017-05-28C++获取zip文件列表方法
  • 2017-05-28详解C++编程中数组的基本用法
  • 2017-05-28详解数据结构C语言实现之循环队列
  • 2017-05-28探讨数组与字符串输入的问题(C++版)
  • 2017-05-28初学C++之自定义类型名简化详解
  • 2017-05-28变量定义与声明的区别详细解析
  • 2017-05-28C++中 静态局部变量实例详解
  • 2017-05-28C 语言指针概念的详解

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C语言数据结构中二分查找递归非递归实现并分析
    • c语言动态数组示例
    • C++动态内存分配(new/new[]和delete/delete[])详解
    • C++类中的常数据成员与静态数据成员之间的区别
    • 使用C语言的fork()函数在Linux中创建进程的实例讲解
    • 从汇编看c++的默认析构函数的使用详解
    • c语言连接mysql数据库的实现方法
    • C++对数组的引用实例分析
    • C++读写.mat文件的方法
    • C++的static关键字及变量存储位置总结

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有