精华内容
参与话题
问答
  • Windows程序内部运行原理 为了理解Visual C++应用程序开发过程,先要理解Windows程序的运行机制。因为 Visual C++是 Windows 开发语言,需要明白在 Windows 环境下编程和在其它环境下编程的一些根本性的差别。全面...
    Windows程序内部运行原理

     

    为了理解Visual C++应用程序开发过程,先要理解Windows程序的运行机制。因为 Visual C++ Windows 开发语言,需要明白在 Windows 环境下编程和在其它环境下编程的一些根本性的差别。全面地讨论 Windows 的内部工作机制将需要整整一本书的容量,没有必要深入了解所有的技术细节。但是对于Windows程序运行的一些根本性的概念,是一个Visual C++程序员所必须掌握的知识。

     

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

        WINDOWS程序设计是一种完全不同于传统的DOS方式的程序设计方法,它是一种事件驱动方式的程序设计模式,主要是基于消息的。当用户需要完成某种功能时会调用操作系统的某种支持,然后操作系统将用户的需要包装成消息,并投递到消息队列中,最后应用程序从消息队列中取走消息并进行响应。

    我们这样解释上面的例,向下的箭头1表示操作系统能够操纵输出设备,以执行特定的功能,如让声卡发出声音,让显卡画出图形。向上的箭头2表示操作系统能够感知输入设备状态的变化,如鼠标移动,键盘按下,并且能够知道鼠标移动的具体位置,键盘按下的哪个字符。这就是操作系统和计算机硬件之间的交互关系,应用程序开发者通常不需知道其具体实现细节。

     

    2.1.1 关于API

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

    那么,应用程序是如何通知操作系统执行某个功能的呢?有过编程经验的读者都应该知道,在应用程序中要完成某个功能,都是以函数调用的形式实现的,同样,应用程序也是以函数调用的方式来通知操作系统执行相应的功能的。操作系统所能够完成的每一个特殊功能通常都有一个函数与其对应,也就是说,操作系统把它所能够完成的功能以函数的形式提供给应用程序使用,应用程序对这些函数的调用就叫做系统调用,这些函数的集合就是Windows操作系统提供给应用程序编程的接口(Application Programming Interface),简称Windows API。如CreateWindow就是一个API函数,应用程序中调用这个函数,操作系统就会按照该函数提供的参数信息产生一个相应的窗口。大家不妨看看EX02_00中的源程序,体会一下在程序中是如何调用这个CreateWindow API函数的,关于这个函数的详细解释,请参阅MSDN(微软开发编程的开发系统)

    顺便提一下,对于一个真正的程序员来说,不可能死记硬背每一个API函数及其各参数的详细信息。通常都是只记住其英文拼写,有时甚至是凭着语意拼读出来的,如显示窗口用ShowWindow,退出Windows操作系统用ExitWindows等等,API函数的正确拼写格式及各参数的祥尽信息都是在MSDN迅速检索到的,没必要刻意去死记这些信息,等用的次数多了,这些信息也就在不知不觉中掌握了,但一定要具备在需要的时候能够从帮助系统中检索想要的信息的能力,这样就能做到事半功倍。学习VC++,一定要有一套真实的练习环境,学会查阅帮助系统,决不能纸上谈兵,照着书本亦步亦趋,否则就真的是没有一两年的时间,是学不好VC++的了。

    注意:请不要将这里的APIjava API以及其他API混淆。API正如其语义一样,已成为一种被广泛使用的专业术语。如果某个系统或某个设备提供给某种应用程序对其进行编程操作的函数,类,组件等的集合,就称作该系统的API。曾经有学员问我这样的问题,Java APIwindows API有何关系,是不是指java也可以调用windows里的API?读者现在应该明白这个问题了,不需我来回答了吧?

     

    2.1.2 关于消息及消息队列

    向上的箭头4表示操作系统能够将输入设备的变化上传给应用程序。如用户在某个程序活动时按了一下键盘,操作系统马上能够感知到这一事件,并且能够知道用户按下的是哪一个键,操作系统并不决定对这一事件如何作出反应,而是将这一事件转交给应用程序,由应用程序决定如何对这一事件作出反应。好比有个蚊子叮了我们一口,我们的神经末梢(相当于操作系统)马上感知到这个事件,并传递给了我们的大脑(相当于应用程序),我们的大脑最终决定如何对这一事件作出反应,如将蚊子赶走,或是将蚊子拍死。对事件作出反应的过程就是消息响应,由水平箭头5表示。

    操作系统是怎样将感知到的事件传递给应用程序的呢?这是通过消息机制(Message)来实现的。操作系统将每个事件都包装成一个称为消息的结构体MSG来传递给应用程序的,参看MSDN

    MSG结构定义如下:

    复制代码
    Code
    
    展开全文
  • WINDOWS程序内部运行原理

    千次阅读 2012-06-05 16:00:35
    API(Application programming interface) 应用程序编程的接口 MSG(message) 消息结构体  操作系统将每一个事件包装成一...MSG的结构定义如下:(windows user interface : platform sdk ) Typedef struct tagMSG{
    
    

    API(Application programming interface) 应用程序编程的接口

    MSG(message)  消息结构体   

    操作系统将每一个事件包装成一个称为消息MSG的结构体传递给应用程序

    MSG的结构定义如下:(windows user interface : platform sdk )

    Typedef struct tagMSG{

                  HWND hwnd;  窗口的句柄  句柄为资源的标识,按类型分为HICON /HCURSOR /HWND /HINSTANCE

                  UINT message;      无符号整形具体的消息; 用宏来表示数值WM开头的为宏WM_*

                  WPARAM wParam;  整型. 关于消息的附加信息. WM_CHAR消息字符的代码ASCII;

                  LPARAM lParam;   ;整型. 关于消息的附加信息. PARAM=PARAMETER参数,参量

                  DWORD time;      ;WORD16位的整数DWORD=Double WORD32位整数.指定消息的投递时间.

                  POINT pt;          当消息被投递的时候光标太屏幕上的坐标;

    }MSG,*PMSG;

    POINT为一个结构体定义了点x坐标y坐标

    Typedef struct tagPOINT{

                  LONG x;

                  LONG y;

    } POINT,*PPOINT;                                                    结束时间2009年2月19日4:57:49

    2009年2月20日13:18:04(第二次)

    消息:消息本身,特定的消息响应

    WINMAN函数

    入口点函数类似于C的MAN函数

    int WINAPI WinMan(

                  HINSTANCE hInstance,      //handle to cerrent instance   实例(资源)的句柄,当前运行的句柄;

                  HINSTANCE hPrevinstance,  //handle to previous instance  先前实例的句柄,可能为空,兄弟的实例句柄

    win32下这个实例总是为空(win98、2000等);

                  LPSTR lpCndLine,          //command line  LP->LONG POINTER长指针,ETRING字符串,指向字符

    串的指针;类似于CHAR *   命令行参数

                  int nCmdSbow              //show state  显示的状态,比如窗口的大小全屏

    )   //这个分号在具体的编程过程中是不要的,需要删除掉。

    DOS下的MAIN函数可以接收2个参数:ARJc、ARJv. ARJc用来接受、存放命令行参数的个数,ARJv指针数组用来存放命令行参数,同样的在windows程序当中他也可以接收命令行的参数.

    WINAPI :Calling convention for system functions.

    2009年2月24日15:10:15(第三次)

    窗口的创建。创建一个完整的窗口需要经过下面四个操作步骤:

    l         设计一个窗口类;

    l         注册窗口类;

    l         创建窗口;

    l         显示及更新窗口;

    1、设计窗口。设计一个窗口就是设计一个窗口类,他是一个结构体

    WNDCLASS

    Typedef struct _WNDCLASS{     //MSDN--WNDCLASS

    UINIT style;   style //(Class Styles=CS)指定一个类的类型,这里是窗口类的类型;OR(|),与(&),取反(~),

                           赋值:wndclass.style=CS_HREDRAW | CS_VREDRAW (水平和垂直重画)

    WNDPROC lpfnWndProc; 窗口过程。Lp=long pointer.fn=functionProc= procedure用来接收一个函数指针。

    回掉函数(lpfnWndProc: Pointer to the window procedure. You must use the

    CallWindowProc[回调window进程] function to call the window procedure. For more

    information, see WindowProc.)。这里我们会把一个窗口名赋给他(函数名相当于一个

    函数的指针),即在设计的时候就确定了一个回调函数,这里给他赋了WinSunProc

    这个函数,当然WinSunProc函数具体内容是什么需要程序员自己去编写。

    int  cbClsExtra;   windows程序会为每一个类管理一个内部数据结构。类附加内存,通常情况下设为零.(=0

                             类额外的一个数据。(附加字节数)

    int  cbWndExtra;  windows程序会为每一个窗口管理一个内部数据结构。窗口附加内存,通常情况下也设

    置为零。以上两个分配额外的内存,通常我们不需要所以设置为零。(=0)

    窗口类额外的一个数据。通常赋值为零表示我们不需要额外的内存,但是如果我们需要则额外的内存空间会自己变为零。这里设置为零就是=0,不同于其他的设置为NULL,因为这里是整数。

    HANDLE  hInstance;   代表我们当前程序的实例号。操作系统分配,直接通过WinMain的形参传递过来。

    代表了我们当前应用程序的实例号,我们在设计窗口类的时候需要知道他是代表那

    个应用程序实例的。从bInstance获得这个程序。

    HICON   hIcon;   图标的句柄。用LoadIcon这个函数来赋值 hIcon=LoadIcon(……)

    HCURSOR  hCursor; 光标句柄。用LoadCursor这个函数来赋值hCursor=LoadCursor(……)

    HBRUSH  hbrBackground;  画刷的句柄,用的是GetStockObject()这么一个函数

    LPCTSTR lpszMenuName;  LP=long point(32位),CT=constant常量,STR=string.用来设定菜单的名字

    可以直接设置为空NULL,如:lpszMenuNam=NULL;

     (如果这个类型不认识可以用data type 这个来查看不是SDK)

    LPCTSTR lpszClassName;  设置一个类的名字(注册窗口的时候会用到),窗口设计完成之后需要给窗口取一

    个名字。

    }WNDCLASS,*PWNDCLASS;

    这个函数是系统定义好了格式,我们只需要拿过来用,直接对参数进行赋值。

    WindowProc 回调函数,窗口过程函数

    LRESULT CALLBACK WindowProc(   //CALLBACK:窗口过程函数前边定义的时候加了一个CALLBACK

                                        #define CALLBACK  _stdcall

                                        CALLBACK就是一个类型的定义

                                        LRESULT就是一个长整型,返回一个结果码。

      HWND hwnd,      // handle to window

      UINT uMsg,      // message identifier

      WPARAM wParam,  // first message parameter

      LPARAM lParam   // second message parameter

    );

    DefWindowProc回调函数,窗口过程函数

    LRESULT DefWindowProc(

      HWND hWnd,      // handle to window

      UINT Msg,       // message identifier

      WPARAM wParam,  // first message parameter

      LPARAM lParam   // second message parameter

    );

    _stdcall和_cdecl这是两种调用的约定,_stdcall标准调用约定,_cdecl为c语言的调用约定。标准调用约定也是PASCAL调用约定,dephi就是pascal调用约定。_stdcall和_cdecl在参数的传递顺序和堆栈的清除这两个方面有差异。Vc++默认的调用约定选项是_cdecl.需要时要经行定义。也可以通过Project -> Project Settings ->C/C++ ->Calling convention:中选择_stdcall这种方式来设定。

    LoadIcon

    HICON LoadIcon(

        HINSTANCE hInstance, // handle to application instance 应用程序实例的一个句柄。当标准的图标加载的
    时候这个参数用空(NULL),

    LPCTSTR lpIconName  // name string or resource identifier当第一个参数取值为NULL时第二个参数可以选择

    );

    如:LoadIcon(NULL,IDI_ERROR)     // ID=identifier

    LoadCursor

    HCURSOR LoadCursor(

    HINSTANCE hInstance,  // handle to application instance 应用程序实例的一个句柄,如果想用一个标准的光标

    这个参数需要设置为NULL

    LPCTSTR lpCursorName  // name or resource identifier  同样当前一个参数设置为NULL是这个可以选择微

    软提供的光标函数。

    );

    GetStockObject()  获取一个笔、画刷、调色板、的句柄。

    HGDIOBJ GetStockObject(

      int fnObject   // stock object type

    );

    *=(HBRUSH) GetStockObject(WHITE_BRUSH);   // (HBRUSH) 这里是一个强制转换。因为GetStockObject返回的是一个GetStockObject的类型,而hbrBackground定义的为HBRUSH的类型,C++语言是一个强类型语言,对函数的类型要求的很严。强制类型转换必须要有可比性,即两个类型可以转换,这种转换在编译的时候不会报错但是在执行的时候会出现错误。

    2、注册。窗口设置完之后需要对其进行注册(向操作系统注册),RegisterClass()窗口的注册函数

    RegisterClass

    ATOM RegisterClass(

      CONST WNDCLASS *lpWndClass  // class data 窗口类结构体的指针直接用定义的窗口类结构体的变量加上取

    地址符&

    );

    3、创建一个窗口

    首先需要定义一个句柄(HWND),利用这个句柄的变量保存我们新创建的窗口的标识。然后利用CreateWindow函数来进行窗口的创建。

    HWND hwnd;

    Hwnd=CreateWindow(……);

    CreateWindow

    HWND CreateWindow(

      LPCTSTR lpClassName,  // registered class name 注册的类名,设计窗口类的时候指定的名字,如果名称与开始

    定义的不一样那么WinMain程序会运行但是窗口是不回产生的。创建窗口的时候一

    定要基于一个已经注册之后的窗口类名来设定

      LPCTSTR lpWindowName, // window name  窗口的名字,即我们产生这个窗口的时候他的标题。在标题栏上显

    示的窗口的名字,标题栏是一条蓝色的在窗口顶端的长条

      DWORD dwStyle,        // window style  窗口的类型,要和刚才的类的类型区分开来。(WS)如:

    WS_OVERLAPPEDWINDOW

      int x,                // horizontal position of window 窗口的水平坐标; CW_USEDEFAULT,如果x设置为

    CW_USEDEFAULT(系统缺省坐标)那么y坐标值就会被忽略。另外屏幕坐标左上角为

    原点(0,0)而数学中的为左下角是原点

      int y,                // vertical position of window  窗口的垂直坐标; x,y显示的时候窗口的左上角的x,y坐标.

      int nWidth,           // window width 窗口的宽度,CW_USEDEFAULT用的是系统缺省的宽度和高度。同样

    如果用CW_USEDEFAULT则nHeight会被忽略。

      int nHeight,          // window height 窗口的高度

      HWND hWndParent,   // handle to parent or owner window 窗口的句柄,这里指的是父窗口的句柄,如果程

    序只有1个窗口没有父窗口则可以设置为空(NULL)

      HMENU hMenu,      // menu handle or child identifier  菜单的句柄。如果用不倒菜单那么我们可以把菜单句柄

    设置为空(NULL);

      HINSTANCE hInstance,  // handle to application instance 当前应用程序实例的句柄,通过WinMain函数传递过

    来,直接把实例号hInstance,复制过来就可以了

      LPVOID lpParam      // window-creation data  当窗口创建的时候都会有WM_CREATE这个消息产生,

    作为WM_CREATE的附加消息有两个由lParam的消息内容传进来。指向

    CREATESTRUCT结构体,该结构题的lParam参数是通过创建窗口时产生的

    WM_CREATE消息时产生的附加消息中的lParam参数传递过来的,即:作为

    WM_CREATE附加消息lParam传递过来的参数数据的指针。如果一个应有实例

    CreateWindow创建一个多文档multiple document interface (MDI)界面的窗口该函数

    lpParam指针指向结构体CLIENTCREATESTRUCT

    );

     

    WS_OVERLAPPEDWINDOW

    WS_OVERLAPPEDWINDOW(

    WS_OVERLAPPED      |    //标识产生一个层叠的窗口,层叠的窗口就是有一个标题栏还有一个边框

    WS_CAPTION          |    //创建一个有标题栏的窗口

    WS_SYSMENU         |    //创建一个带有系统菜单的窗口

    WS_THICKFRAME      |    //创建一个具有可调边框的窗口

    WS_MINIMIZEBOX     |     //创建一个具有最小化按钮的窗口

    WS_MAXIMIZEBOX         //创建一个具有最大化按钮的窗口

    ). Same as the WS_TILEDWINDOW style. 

    上边的特征都是有二进制位表示有无。

    CREATESTRUCT

    typedef struct tagCREATESTRUCT {

        LPVOID    lpCreateParams;

        HINSTANCE hInstance;

        HMENU     hMenu;

        HWND      hwndParent;

        int       cy;

        int       cx;

        int       y;

        int       x;

        LONG      style;

        LPCTSTR   lpszName;

        LPCTSTR   lpszClass;

        DWORD     dwExStyle;

    } CREATESTRUCT, *LPCREATESTRUCT;

    WM_CREATE    WindowProc

    LRESULT CALLBACK WindowProc(

      HWND hwnd,       // handle to window

      UINT uMsg,       // WM_CREATE

      WPARAM wParam,   // not used

      LPARAM lParam    // creation data (LPCREATESTRUCT)

    );

    4、显示、更新窗口

    窗口创建完之后需要显示出来。显示窗口调用函数为:ShowWindow

    ShowWindow  指定窗口的显示状态

    BOOL ShowWindow(

      HWND hWnd,     // handle to window 窗口的句柄,即要显示的是哪一个窗口,把窗口的标识赋给他

      int nCmdShow   // show state 窗口的显示状态。如:最大化显示,最小化显示等。(SHOW_SHOWNORMAL

    正常化显示)

    );

    UpdateWindow

    显示完窗口之后我们还需要调用一个函数,即为更新窗口的函数,UpdateWindow。当然这个函数如果不添加也不影响窗口的产生。

    BOOL UpdateWindow(

      HWND hWnd   // handle to window  窗口句柄。

    );

    消息循环,这里最重要的环节。

    首先用MSG结构体定义了一个消息结构体的变量。用While循环对GetMessage进行循环。GetMessage调用消息队列中的消息。

    MSG msg;

    While(GetMessage(&msg,NULL,0,0)) //GetMessage取到的消息不是WM_QUIT时执行While循环。

    {

         TranslateMessage(&msg);    // 转换消息,翻译消息。对取到的消息对进行转换。当我们按下某一个按键

    的时候系统将会产生一个WM_KEYDOWN和WM_KEYUP这样两个的消

    息,并提供一个按键的虚拟的扫描码。TranslateMessage将WM_KEYDOWN

    和WM_KEYUP消息对转换成ASCII码WM_CHAR消息,并将转换后的消息

    投递到消息队列中,转换过程中不会影响原来的消息只会产生一个新的消

    息。如果不用这个函数那么我们不可能收到WM_CHAR消息的。

         DispatchMessage(&msg);    // 将收到的消息(TranslateMessage(&msg)转换的消息)传递到窗口的回调函数

    即窗口的过程函数中处理,即将消息路由给了操作系统,然后操作系统去调

    用窗口过程函数,即我们在设计窗口类WNDCLASS的时候设计的窗口过程

    函数WNDPROC lpfnWndProc 所设定的回调函数进行处理。

    }

    GetMessage

    BOOL GetMessage(    // 如果返回值是WM_QUIT则返回一个零值,如果返回的不是WM_QUIT则返回的是一

    个非零值。

    LPMSG lpMsg,         // message information   [out] Pointer to an MSG structure that receives message

    information from the thread's(线程) message queue. 消

    息结构体的指针。

      HWND hWnd,           // handle to window   句柄表示想要获取那个窗口的消息,如果设置为NULL,标识

    我们要获取属于这个调用线程的任何窗口的消息

      UINT wMsgFilterMin,  // first message         指定消息的最小的消息值

      UINT wMsgFilterMax   // last message         指定一个消息的最大的消息值,即最后一个消息(MSDN有一

    个错误他将last写成first)如果这两个都设置为零那么

    GetMessage就没有对消息进行过滤而是针对所有的消息,没有

    范围的过滤。

    );

    [out]->表明我在对lpMsg传参的时候不要对内部成员经行初始化,只需要定义一个结构体的变量将他的地址放在哪里,通过函数的调用他会自动的填充消息结构体内部的成员变量。

    GetMessag返回的是一个BOOL型的值。当从消息队列中取回消息是返回值为真,当消息队列中始终都有的消息的时候则返回的值始终都是真。

    TranslateMessage

    BOOL TranslateMessage(

      CONST MSG *lpMsg   // message information

    );

    DispatchMessage

    LRESULT DispatchMessage(

      CONST MSG *lpmsg   // message information

    );

    窗口过程函数(WNDPROC lpfnWndProc指定的函数),即回调函数里边的代码

    这里设定的窗口调用函数的名称为WinSunProc.怎么知道WinSunProc是什么样的格式呢?选择查看的方式如下:

     WNDCLASS -> Platform SDK: Windows User Interface -> 选择see WindowProc 中的WindowProc ->我们可以看到函数的形式规定的形式(函数名称可以更改,但是参数的类型不能更改但参数的名字可以更改):

    LRESULT CALLBACK WindowProc(     // LRESULT就是一个LONG型 CALLBACK后边将介绍

      HWND hwnd,      // handle to window   窗口的句柄

      UINT uMsg,      // message identifier    消息的标识

      WPARAM wParam,  // first message parameter     消息的附加参数

      LPARAM lParam   // second message parameter    消息的第二个附加参数

    );

    实际上是将消息结构体的前四个参数作为参数传递给WindowProc(这个名称用户可以自己更改)

    sprintf: printf在c语言中是想屏幕中输出内容,sprintf是c语言中的一个库函数,是格式化一个文本到内存buffer中,即一个内存区中.指定的区域中打印一些数据的。如下:

    char szChar[20];

    sprintf(szChar,”char is %d”,wParam);   //将wParam的ASCII码的消息以%d的格式格式化到szChar这个字符数组

    当中。

    MessageBox(hwnd,szChar,”weixin”,MB_ok);   // MessageBox用来弹出一个消息框.

    MessageBox

    int MessageBox(

      HWND hWnd,       // handle to owner window   消息框被创建那个窗口拥有这个消息框的句柄

      LPCTSTR lpText,     // text in message box       消息显示的文本

      LPCTSTR lpCaption,  // message box title         消息的标题,即在消息的蓝框中的内容显示

      UINT uType          // message box style        消息框的类型,如MB_OK表示消息框包含了一个OK按键

    的button按钮。MB_OK定义的是”0”,我们可以直接用”0”代

    MB_OK .

    );

    文字的输出

    HDC hDC;       // HDC是一个句柄,DC(device context设备上下文)的句柄。DC是系统内部维护的数据结构占

    内存。

    hDC=GetDC(hwnd); //获取函数hDC的句柄

    TextOut(hDC,0,50,” 计算机编程语言培训”,strlen(“计算机编程语言培训”)); //文本输出的函数,在窗口上输出一个

    文本。

    ReleaseDC(hwnd,hDC);   //释放DC.如果我们使用了一个DC而没有在使用完之后释放DC那么会造成内存的泄

    露。   GetDCReleaseDC是一对

    HDC

    Handle to a device context (DC).

    GetDC

    HDC GetDC(

      HWND hWnd   // handle to window 窗口的句柄。跟那个窗口相关的DC,利用DC画图的时候就画在那个窗口

    上。

    );

    TextOut

    BOOL TextOut(

      HDC hdc,           // handle to DC   DC的句柄

      int nXStart,       // x-coordinate of starting position  开始x坐标位置

      int nYStart,       // y-coordinate of starting position   开始y坐标位置

      LPCTSTR lpString,  // character string   输出文本内容

      int cbString       // number of characters  输出文本字符数量。 用c的strlen.

    );

    WM_PAINT  当窗口重绘的时候就会发送这个消息。当窗口从无到有的时候会使用这个函数,同时在我们在调试运行时设置的断点中不能在WM_PAINT中设置,如果这样做了那么窗口将会永远不会产生。前面说过当我们窗口的水平或者垂直坐标发生改变的时候窗口都会重绘,重绘就是通过发送WM_PAINT这个消息来完成的。

    Case WM_PAINT: //窗口的绘画,下边为响应消息的设置

    hdc=BeginPaint(hwnd,&ps); // 获取DC的句柄,这个DC是在选择语句上边预定的。

    TextOut(hdc,0,0,” 北京维新科学技术培训中心”,strlen(”北京维新科学技术培训中心”));  //

    EndPaint(hwnd,&ps);  //释放DC.BeginPaint和EndPaint是一对,并且只能在WM_PAINT上使用。 

    break;

    BeginPaint

    HDC BeginPaint(

      HWND hwnd,            // handle to window   窗口的句柄

      LPPAINTSTRUCT lpPaint // paint information  设置PAINTSTRUCT结构体的指针。

    );

    BeginPaint准备为指定的窗口进行绘画,BeginPaint函数自动填充PAINTSTRUCT结构体,PAINTSTRUCT结构体不需要我们来维护由系统内部lpPaint来维护

    PAINTSTRUCT

    typedef struct tagPAINTSTRUCT {

      HDC  hdc;

      BOOL fErase;

      RECT rcPaint;

      BOOL fRestore;

      BOOL fIncUpdate;

      BYTE rgbReserved[32];

    } PAINTSTRUCT, *PPAINTSTRUCT;

    WM_CLOSE

    case WM_CLOSE: //当我们点击关闭按钮的时候会产生这样的消息。

    if(IDYES= = MessageBox(hwnd,”你是否要退出程序?”,”weixin”,MB_YESNO)) //由MessageBox返回一个ID*

    的参数,判断该返回参数与IDYES的比较情况。

    {

        DestroyWindow(hwnd); //  销毁窗口

    }

    break;

    IDYES是一个常量,我们在程序设计的是有有一个小经验:在if语句判断的时候一般把常量放在前边。这样做方便我们找到错误。如:if(x=1)if(1=x),这两种是在我们输入的时候容易出错的两种情况,第二种在编译的时候就会报错,而第一种x=1是“真”,编译的时候不会报错。

    DestroyWindow

    BOOL DestroyWindow(

      HWND hWnd   // handle to window to destroy  //要被销毁的窗口的句柄。

    );

    DestroyWindow 这个函数会发送WM_DESTROY 和WM_NCDESTROY这两个消息到消息队列中。

    WM_DESTROY

    Case WM_DESTROY

         PostQuitMessage(0);

         Break;

    小经验:

    case WM_CLOSE:

    if(IDYES= = MessageBox(hwnd,”你是否要退出程序?”,”weixin”,MB_YESNO))

    {

        DestroyWindow(hwnd);

    }

    break;

    Case WM_DESTROY

         PostQuitMessage(0);

         Break;

    这个程序片段的意思是当MessageBox弹出后用户选择YES时,if语句为真,执行DestroyWindow(hwnd)关掉窗口,同时产生WM_SESTROY和WM_NCDESTROY两个消息,在case WM_DESTROY中将关掉程序执行的进程,同时程序结束。

    case WM_CLOSE:

    DestroyWindow(hwnd);

    break;

    Case WM_DESTROY

         if(IDYES= = MessageBox(hwnd,”你是否要退出程序?”,”weixin”,MB_YESNO))

         {

     PostQuitMessage(0);

         }

         Break;

    这个程序片段与上边的略有不同,但是执行结果则是完全不一样的。当执行WM_CLOSE时程序会首先执行DestroyWindow(hwnd)关掉窗口产生WM_SESTROYWM_NCDESTROY两个消息到消息对立中,这个时候响应消息WM_DESTROY,开始执行if的判断,此时才弹出MessageBox的消息对话框,如果用户选择的是否,那么消息对话框关闭了,if语句为否不执行其中的PostQuitMessage(0)也就无法产生WM_QUIT消息,此时窗口关闭了,但是程序没有终止而是在后台中运行。

    PostQuitMessage

    VOID PostQuitMessage(       //产生WM_QUIT这个消息

      int nExitCode              // exit code

    );

    default

    在写消息循环的时候default语句是必不可少的,是对缺省的没有定义的消息由系统进行默认的响应,如果没有那么那些没有定义的消息将会缺少归宿,并且窗口可能不能正常的显示,但是程序还是在后台运行。

    deault:

         return DefWindowProc(hwnd,uMsg,wParam,lParem);

    return 0;

    函数的正常返回值,返回一个”0”值。

    编写一个程序:

    新建一个projectFile ->New…->Projects ->Win32 Application |Location:存放地址|Project name:工程名字 ->OK ->step 1:An empt project -> finish ->ok .

    新建:File ->New…->Files ->c++ source file(c++源文件)|file:同样的名字 ->ok.

    既然我们编写的是windows程序,所以就要包含#include <windows.h>  windows头文件 ,还有一个就是c语言的头文件#include <stdio.h> 原因是我们要用到c语言的库函数。

    --------------------------------------------------------------------------------------------------------------------------------------

    #include <windows.h>

    #include <stdio.h>

     

    LRESULT CALLBACK WinSunProc(    //可以通过MSDN查找,不过函数的名称要根据自己的需要修改。

      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(WHITE_BRUSH);

           wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);

           wndcls.hIcon=LoadIcon(NULL,IDI_QUESTION);

           wndcls.hInstance=hInstance;

           wndcls.lpfnWndProc=WinSunProc;

           wndcls.lpszClassName="liqiang2009";

           wndcls.lpszMenuName=NULL;

           wndcls.style=CS_HREDRAW|CS_VREDRAW;

           RegisterClass(&wndcls);

     

           HWND hwnd;

           hwnd=CreateWindow("liqiang2009","一个简单的窗口",WS_OVERLAPPEDWINDOW,

                  CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,

                  NULL,NULL,hInstance,NULL);

     

           ShowWindow(hwnd,SW_SHOWNORMAL);

           UpdateWindow(hwnd);

     

           MSG msg;

           while(GetMessage(&msg,NULL,0,0))

           {

                  TranslateMessage(&msg);

                  DispatchMessage(&msg);

           }

           return 0;

    }

     

    LRESULT CALLBACK WinSunProc(

      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,"您所输入的按键值为:%d%c",wParam,wParam);

                  MessageBox(hwnd,szChar,"按键值",0);

                  break;

           case WM_LBUTTONDOWN:

                  MessageBox(hwnd,"您按下了鼠标的左键","按键值",0);

                  HDC hdc;

                  hdc=GetDC(hwnd);

                  TextOut(hdc,0,25,"HDC hdc",strlen("HDC hdc"));

                  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,"是否真的退出?","询问窗口",MB_YESNO))

                  {

                         DestroyWindow(hwnd);

                  }

                  break;

           case WM_DESTROY:

                  PostQuitMessage(0);

                  break;

           default:

                  return DefWindowProc(hwnd,uMsg,wParam,lParam);

           }

           return 0;

    }

    ------------------------------------------------------------------------------------------------------------------------------------------

    Build Log

    --------------------Configuration: WinMain - Win32 Debug--------------------

    Command Lines

    Creating temporary file "C:/DOCUME~1/Li/LOCALS~1/Temp/RSPFE.tmp" with contents

    [

    /nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Fp"Debug/WinMain.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c

    "D:/soft-教程/vc++/孙鑫课件/lessons/lesson1/WinMain/WinMain.cpp"

    ]

    Creating command line "cl.exe @C:/DOCUME~1/Li/LOCALS~1/Temp/RSPFE.tmp"

    Creating temporary file "C:/DOCUME~1/Li/LOCALS~1/Temp/RSPFF.tmp" with contents

    [

    kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /incremental:yes /pdb:"Debug/WinMain.pdb" /debug /machine:I386 /out:"Debug/WinMain.exe" /pdbtype:sept

    "./Debug/WinMain.obj"

    ]

    Creating command line "link.exe @C:/DOCUME~1/Li/LOCALS~1/Temp/RSPFF.tmp"

    Output Window

    Compiling...

    WinMain.cpp

    Linking...

    Results

    WinMain.exe - 0 error(s), 0 warning(s)

     

    编写程序后小结:

    第一个小结:

           case WM_CLOSE:

                  if(IDYES==MessageBox(hwnd,"是否真的退出?","询问窗口",MB_YESNO))

                  {

                         DestroyWindow(hwnd);

                  }

                  break;

           case WM_DESTROY:

                  PostQuitMessage(0);

                  break;

    可以直接关闭而不弹窗修改为:

           case WM_CLOSE:

                  DestroyWindow(hwnd);

                  break;

           case WM_DESTROY:

                  PostQuitMessage(0);

                  break;

    第二个小结:

           case WM_PAINT:

                  HDC hDC;

                  PAINTSTRUCT ps;

                  hDC=BeginPaint(hwnd,&ps);

                  TextOut(hDC,0,0,"重刷的时候不会被去掉的文字",strlen("重刷的时候不会被去掉的文字"));

                  TextOut(hDC,0,25,szChar,strlen(szChar));

                  EndPaint(hwnd,&ps);

                  break;

    TextOut可以用多次,多次使用时只要不是文字的覆盖那么每次TextOut的执行不会清除上一次的结果。

    第三个小结:

    变量可以设置为全局的但是程序不能设置为全局的,如:

    #include <windows.h>

    #include <stdio.h>

           char szChar[26];

    ……

    第四个小结:

    函数调用时,被调用的函数需要提前做定义,同时使用的时候要和定义的函数名称一致,否则程序无法执行。

    第五个小结:

    当程序修改后调试的时候必须将以前调试运行的程序关闭,否则会出现错误:

    --------------------Configuration: WinMain - Win32 Debug--------------------

    Linking...

    LINK : fatal error LNK1168: cannot open Debug/WinMain.exe for writing

    Error executing link.exe.

     

    WinMain.exe - 1 error(s), 0 warning(s)

    第六个小结:

    /0,/n etc.在sprintf();中不起任何作用。

    第七个小结:

    Sprintf中可以有多个参数的变量,如同时有%d、%c etc.

    sprintf(szChar,"您所输入的值为:/n %d,%c   ",wParam,wParam);

    遇到一个问题:

    当关掉编译器后双击*.cpp这个文件的时候会打开编译器,但是编译运行的时候系统就会报错!!!

    Build Log

    --------------------Configuration: WinMain - Win32 Debug--------------------

    Command Lines

    Creating temporary file "C:/DOCUME~1/Li/LOCALS~1/Temp/RSP13C.tmp" with contents
    [
    kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"Debug/WinMain.pdb" /debug /machine:I386 /out:"Debug/WinMain.exe" /pdbtype:sept 
    "./Debug/WinMain.obj"
    ]
    Creating command line "link.exe @C:/DOCUME~1/Li/LOCALS~1/Temp/RSP13C.tmp"

    Output Window

     
    Linking...
    LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
    Debug/WinMain.exe : fatal error LNK1120: 1 unresolved externals
    Error executing link.exe.

    Results

    WinMain.exe - 2 error(s), 0 warning(s)

    自己修改的程序:

    #include <windows.h>

    #include <stdio.h>

           char szChar[26];

     

    LRESULT CALLBACK WinSunProc(    //可以通过MSDN查找,不过函数的名称要根据自己的需要修改。

      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

      )

    {

           sprintf(szChar,"你好");  //要想对szChar屏幕输出的时候无乱码,sprintf要放在主函数里对scChar定义。

     

           WNDCLASS wndcls;

           wndcls.cbClsExtra=0;

           wndcls.cbWndExtra=0;

           wndcls.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);

           wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);

           wndcls.hIcon=LoadIcon(NULL,IDI_QUESTION);

           wndcls.hInstance=hInstance;

           wndcls.lpfnWndProc=WinSunProc; 

           wndcls.lpszClassName="liqiang2009";

           wndcls.lpszMenuName=NULL;

           wndcls.style=CS_HREDRAW|CS_VREDRAW;

           RegisterClass(&wndcls);

     

           HWND hwnd;

           hwnd=CreateWindow("liqiang2009","一个简单的窗口",WS_OVERLAPPEDWINDOW,

                  CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,

                  NULL,NULL,hInstance,NULL);

     

           ShowWindow(hwnd,SW_SHOWNORMAL);

           UpdateWindow(hwnd);

     

                 

     

           MSG msg;

           while(GetMessage(&msg,NULL,0,0))

           {

                  TranslateMessage(&msg);

                  DispatchMessage(&msg);

           }

           return 0;

    }

     

    LRESULT CALLBACK WinSunProc(

      HWND hwnd,      // handle to window

      UINT uMsg,      // message identifier

      WPARAM wParam,  // first message parameter

      LPARAM lParam   // second message parameter

    )

    {

    //     char szChar[22];

    //     sprintf(szChar," 你好");

           switch(uMsg)

           {

           case WM_CHAR:

                  HDC hdcc;

                  hdcc=GetDC(hwnd);

                  sprintf(szChar,"您所输入的值为:/n %d,%c   ",wParam,wParam);

                  TextOut(hdcc,0,75,szChar,strlen(szChar));

                  MessageBox(hwnd,szChar,"按键值",0);

                  ReleaseDC(hwnd,hdcc);

                  break;

           case WM_LBUTTONDOWN:

                  MessageBox(hwnd,"您按下了鼠标的左键","按键值",0);

                  HDC hdc;

                  hdc=GetDC(hwnd);

                  TextOut(hdc,0,50,"HDC hdc",strlen("HDC hdc"));

                  ReleaseDC(hwnd,hdc);

                  break;

           case WM_PAINT:

                  HDC hDC;

                  PAINTSTRUCT ps;

                  hDC=BeginPaint(hwnd,&ps);

                  TextOut(hDC,0,0,"重刷的时候不会被去掉的文字",strlen("重刷的时候不会被去掉的文字"));

                  TextOut(hDC,0,25,szChar,strlen(szChar));

                  EndPaint(hwnd,&ps);

                  break;

           case WM_CLOSE:

    //            if(IDYES==MessageBox(hwnd,"是否真的退出?","询问窗口",MB_YESNO))

    //            {

                         DestroyWindow(hwnd);

    //            }

                  break;

           case WM_DESTROY:

                  PostQuitMessage(0);

                  break;

           default:

                  return DefWindowProc(hwnd,uMsg,wParam,lParam);

           }

           return 0;

    }

    展开全文
  • Windows程序内部运行原理的一个示例 一、原理 http://blog.163.com/zhoumhan_0351/blog/static/3995422720103401415721 二、例程 #include"windows.h" #include"stdio.h" LRESULTCALLBACKWinWeProc( HWNDhwnd,...

    Windows程序内部运行原理的一个示例

    一、原理

    http://blog.163.com/zhoumhan_0351/blog/static/3995422720103401415721
    二、例程

    #include "windows.h"

    #include "stdio.h"

    LRESULT CALLBACK WinWeProc(

      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_ASTERISK);

    wndcls.hInstance=hInstance;

    wndcls.lpfnWndProc=WinWeProc;

    wndcls.lpszClassName="WinWe2010";

    wndcls.lpszMenuName=NULL;

    wndcls.style=CS_HREDRAW | CS_VREDRAW;

    RegisterClass(&wndcls);

    HWND hwnd;

    hwnd=CreateWindow("WinWe2010","I am Here",WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,600,400,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 WinWeProc(

      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","message",0);

     HDC hdc;

     hdc=GetDC(hwnd);

     TextOut(hdc,0,50,"MY home",strlen("MY home"));

     ReleaseDC(hwnd,hdc);

     break;

    case WM_PAINT:

     HDC hDc;

     PAINTSTRUCT ps;

     hDc=BeginPaint(hwnd,&ps);

     TextOut(hDc,0,0,"HELLO",strlen("HELLO"));

     EndPaint(hwnd,&ps);

     break;

    case WM_CLOSE:

     if(IDYES==MessageBox(hwnd,"Really?","message",MB_YESNO)){

     DestroyWindow(hwnd);

     }

     break;

    case WM_DESTROY:

     PostQuitMessage(0);

     break;

    default:

     return DefWindowProc(hwnd,uMsg,wParam,lParam);

       }

    return 0;

    }

    三、注意点

    1、wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);

    2、char szChar[20];

     sprintf(szChar,"char code is %d",wParam);

     MessageBox(hwnd,szChar,"char",0);

    3、hdc=GetDC(hwnd);

     TextOut(hdc,0,50,"MY home",strlen("MY home"));

     ReleaseDC(hwnd,hdc);

    //记得GetDC后要ReleaseDC,否则可能内存泄露。在Windows平台下,所有的图形操作操作都是选用DC的,可以把DC想成画布,我们不是作画者,而是指挥者,指挥DC画什么图形。实际上,DC是一个包含设备(物理设备,如输出设备,显示器,及设备驱动程序等)信息的结构体。DC也是一种资源。

    4、hDc=BeginPaint(hwnd,&ps);

     TextOut(hDc,0,0,"HELLO",strlen("HELLO"));

     EndPaint(hwnd,&ps);

    //BeginPaint后要EndPaint,他们是一对,只能用在WM_PAINT消息响应代码中使用。

    5、调用UpdateWindow时,会发送WM_PAINT消息给窗口函数,对窗口函数进行刷新。

    6、逻辑表达式中,当是判断相等时,如果有常量,应当把常量放前面,方便调试和纠错,如下所示:

     if(IDYES==MessageBox(hwnd,"Really?","message",MB_YESNO))

    7、变量的命名约定

     

    展开全文
  • &amp;lt;div class=&quot;simditor-body clearfix&quot; style=&quot;height: auto; overflow: inherit;&quot;&amp;gt; &amp;lt;p style=&quot;text-in
                    <div class="simditor-body clearfix" style="height: auto; overflow: inherit;">
                        
                        <p style="text-indent: 2em;">
    做底层硬件嵌入式的不愿去懂上层PC软件,而做上层PC软件的又不愿去懂底层硬件,做<a href="http://www.elecfans.com/tags/fpga/" target="_blank"><u>FPGA</u></a>不懂FPGA逻辑属硬软核处理器属软。现在,HLS的出现,让FPGA本属于硬件HDL的开发慢慢变成HLS的软件开发,有种当年汇编开发走向C开发的感觉。目前,各大FPGA厂商正在努力搭建HDL到HLS的桥梁,让以后的我们以后能够用HLS高效开发。现在,让我们看看Windows应用程序,操作系统,计算机硬件之间的相互关系,看看它们之间的桥梁如何搭建的。</p>
    

    src="http://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=0.9120230901833388&zoneid=813&prefer=http%3A%2F%2Fwww.elecfans.com%2Fd%2F701778.html" width="675" height="302" scrolling="no">

    其中,上图中,输入输出设备就是计算硬件:键盘、鼠标、耳机等。

    【1】 .操作系统中有很多操作底层的函数接口,也就是我们常说的驱动,这些驱动是直接操作计算机硬件的动作,比如让声卡发出声音。但是,你有没有发现,操作系统可以操作硬件,但是是何时操作了?操作系统不知道,就好比你不买了一个玩具车,装上电池它就可以跑起来,但是你不控制遥控它并不知道要去那;

    【2】.操作系统对设备进行输入、输出和闭环控制。按键鼠标状态输入,显示器输出显示,而硬盘的读写操作就要不断的读取剩余的空间等信息才做有效的写操作的闭环控制。在这里说个题外话:学习学习是不断学和习的闭环,而很多人学的不好就是环没有闭好,理论与实践的结合更恰当的说是理论和实践的闭环,理论与实践如果不闭环就是纸上谈兵和一介武夫而已;

    【3】.前面说过操作系统能很好的去操作底层硬件,但是不知道什么时候去操作和操作到了什么程度,这些都是由应用程序来是实现的,也就是我们常说的应用程序调用API来操作底层硬件,不同的是没有操作系统的单片机由单一的1个Main应用程序去调用API,读取所需要的一个底层设备状态;而有操作系统的PC机由多个应用程序去调用API,读取所需要的多个底层设备的状态。这里就会遇到一个问题,多个应用程序调用API操作相同的底层硬件,这不就乱套了?

    【4】.在这里Windows通过消息队列来处理多个应用程序下的问题:将多个应用程序的操作写入到消息队列中,并按照先写先操作(类似FPGA中的FIFO)的原则去调用API和读取底层设备的状态信息,将时间片切碎分时复用,这种消息队列的处理机制比较复杂,不过没关系,这些都由操作系统来管理并完成,应用程序开发者不用管,开发者开发起来简单方便。

    【5】.操作系统中这种消息队列的机制为多个底层驱动和多个应用程序通信搭建了很好的桥梁,非常方便应用程序和底层驱动的独立开发维护。如果我们搭建的嵌入式系统中没有用到操作系统,底层和应用层开发独立性差,我们完全可以借鉴消息队列这种思维方式来搭建我们的系统架构来独立底层和应用层的开发。

    展开全文
  • windows编程原理

    2008-12-06 16:46:32
    本书详细介绍了windows编程原理,有利于读者了解windows内部编程机制
  • windows下socket编程原理与分步实现

    万次阅读 2020-08-18 17:39:48
    最近在研究msf payload的执行原理,又得用到socket编程的技术,于是就有了这篇文章。 这篇文章跟msf中的技术没多少关系,属于一篇基础文章,看懂这篇文章后继续看msf payload原理就会有一种茅塞顿开的感觉。 ...
  • 该教程为系列教程,后续教程程会持续更新 对当前教程有疑问请在下方留言,我...3.windows内存的运行原理 (1) 什么是内存 (2)进程的边界--虚拟内存空间 (3) 打开进程的边界 4.windows中句柄的概念 5.windows变...
  • 实际上docker只能在linux系统下运行Windows运行必要要支持Hyper-v( 注:windows专业版本才有这个功能)。安装docker的时候会自动创建一个虚拟的linux系统,后续的其他操作实际上是间接使用这个虚拟系统进行的。...
  • (为了方便大家下,我打包了放在一下地址: 1-6:http://download.csdn.net/detail/wangqiulin123456/4601530 7-12:http://download.csdn.net/detail/wangqiulin123456/4601508 13-16:...
  • 看到《Windows内核原理与实现》样书了

    万次阅读 热门讨论 2010-04-27 01:50:00
    今天下午拿到《Windows内核原理与实现》的样书,感觉很好,毕竟期待了这么久,终于看到实物了。过两天要去互动网签名,据说要签200本,赶在五一前发货。我写作这本书的目的是进入课堂,让学生们在学习操作系统时能...
  • Windows程序运行原理

    千次阅读 2013-01-30 06:48:33
    1. Windows应用程序,操作系统,计算机硬件之间的相互关系: 箭头③对应API的调用 箭头④对应操作系统返回事件给应用程序   2. 操作系统充当的角色 操作系统负责管理外围设备,同时与上层的应用程序交互...
  • Windows程序运行原理(总结)

    千次阅读 2016-03-30 11:34:49
    写这个博客的目的仅仅是为自己编程学习过程中作一些总结,时不时来回顾,里面也有没搞明白的,希望在今后积累够后,回来看看能够豁然开朗 1、消息及消息队列:操作系统是将感知到的事件传递给应用程序。 操作...
  • 学习Windows编程的几本好书

    千次阅读 2008-07-24 01:35:00
    学习任何一门知识,都需要相关的数籍,尤其是计算机技术。这里的书籍包括电子书和印刷书籍。对于初学者,最大的痛苦就在于找不到合适的书籍。目前,国内关于计算机类的书籍...当然,我偏爱原理的书籍,因为它能给你一
  • Windows工作原理

    2018-07-15 17:26:00
    Windows工作原理中心思想 Windows工作原理的中心思想就是“动态链接”概念。Windows自身带有一大套函数,应用程序就是通过调用这些函数来实现它的用户界面和在屏幕上显示文本与图形的。这些函数都是在动态链接库里...
  • Windows内核原理与实现》终于完成了

    万次阅读 热门讨论 2010-04-19 23:55:00
    Windows内核原理与实现》终于完成了 经过将近两年的努力,终于完成了《Windows内核原理与实现》一书。2008年春天,我有了写一本关于Windows内核的书的想法,然后联系出版社并付诸实施。这就把两年的业余时间搭了...
  • 编程语言运行原理

    千次阅读 2019-01-16 10:01:50
    先上个图 参考博客:一图看懂编程语言分类...1:汇编/C编译运行原理 预处理, 展开头文件/宏替换/去掉注释/条件编译 (test.i main .i) 编译, 检查语法,生成汇编 ( test.s main .s) (汇编在下一步开始) 汇编...
  • Windows环境下的多线程编程原理与应用 Windows环境下的多线程编程原理与应用
  • WINDOWS程序工作原理(1)

    1970-01-12 18:45:25
    1 WINDOWS程序工作原理WINDOWS程序设计是一种完全不同于传统的DOS方式的程序设计方法,它是一种事件驱动方式的程序设计模式。在程序提供给用户的界面中有许多可操作的可视对象。用户从所有可能的操作中任意选择,被...
  • Windows Hook原理与实现

    万次阅读 多人点赞 2018-08-06 14:38:51
    Windows Hook原理与实现 教程参考自《逆向工程核心原理》 1.概述 Hook技术被广泛应用于安全的多个领域,比如杀毒软件的主动防御功能,涉及到对一些敏感API的监控,就需要对这些API进行Hook;窃取密码的木马...
  • Windows系统服务原理

    千次阅读 2016-07-30 17:39:32
    简单地说,Windows服务是一类Win32可执行程序,通常无界面,由控制台形式的程序实现。这类程序常驻内存,受到操作系统优待。Windows服务(NT服务)分为服务应用程序和内核驱动服务程序,本文利用服务应用程序对检测...
  • Windows操作系统原理.尤晋元.pdf 个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
  • Windows 窗口底层原理

    2020-03-10 11:13:08
    1、Windows程序开发流程: 首先介绍windows程序开发流程:Windows 程序分为「程序代码」和「UI资源」两大部份,两部份最后以RC编译器整合为一个完整的EXE 文件(图1-1)。所谓UI 资源是指功能菜单、对话框外貌、...
  • Windows平台下USB通信原理编程实现_高清版
  • 1、Windows采用双模式来保护操作系统本身,R0和R3。在
  • windows系统的启动工作原理

    千次阅读 2018-06-07 14:24:05
    下面就是windows系统的工作原理 一、Windows系统的启动过程 预了解Windows系统的工作原理,我们先从Windows的启动过程来讲解。同样,我们还是以windows XP为例。首先,从我们按下计算机电源开关,到正式登入到桌面...
  • 浅析Windows程序输入法工作原理

    千次阅读 2018-12-23 22:28:56
    浅析Windows程序输入法工作原理一,输入法结构介绍二,Windows消息循环捕捉键盘消息三,总结 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;输入法程序也是一个进程,但是我们在任务管理器中却找不到该进程,...
  • CATALOGpsexec部分已有资产从被连接主机(lisi)的事件来看psexec到底做了什么从攻击机的流量上来看psexec命令背后做了什么命名管道我理解的命名管道利用具体代码实现服务端代码客户端代码 psexec部分 ...
  • Windows编程

    千次阅读 多人点赞 2015-10-04 22:38:47
    本文整理自百科、知乎与 科学家的世界、Windows编程基础 问题一:为什么开发windows应用程序不用c 而用.net,java,c++? 用 c+windows API 开发windows 应用程序 比用.net,java,c++开发有什么缺点或优点? ...
  •   通过实验,使学生熟悉并掌握计算机Windows 编程的基本知识,进一步加深学生对课堂所学基本内容的理解,掌握基本的Windows编程技巧,通过实验使得学生能够进行一些简单的网络程序设计。 二、实验内容 了解基本的...
  • windows编程经典书籍

    万次阅读 热门讨论 2009-02-18 13:30:00
    本人是刚刚开始学习windows编程的,感觉看雪学院的大牛很NB.想找一些书籍来看学习学习,可是不知道看哪些书好.驱动,对菜鸟们来说真是一个很深奥的话题,所以 ,我找来了这篇文章供大家分享,以后大家发现什么好书就在楼下...

空空如也

1 2 3 4 5 ... 20
收藏数 257,407
精华内容 102,962
关键字:

windows运行原理