《VC++深入详解》学习笔记 第一章 Windows程序内部运行机制

1.API和SDK

2.窗口:通过窗口句柄来标识。

3.句柄(HANDLE):各种资源的标识号。  窗口句柄(HWND) 图标句柄(HICON)光标句柄(HCURSOR) 画刷句柄(HBRUSH)  实例句柄(HINSTANCE)。

4.Windows程序设计,是事件驱动的,主要是基于消息的。

消息:MSG结构体

      Typedef struct tagMSG{

              HWND hwnd;    //表示消息所属的窗口

              UINT message; //消息的标识符,WM_XXX宏(eg:WM_CHAR)

              WPARAM wParam;//消息的附加信息 (eg:WM_CHAR用户输入的具体字符)

              LPARAM lParam;//附加信息 (WPARAM:unsigned int; LPARAM:long)

              DWORD  time;  //消息投递时的时间

              POINT  pt;    //鼠标的当前位置

}MSG;

消息队列:系统为应用程序创建一个消息队列,并将该程序的消息放入消息队列,应用程序通过一个消息循环依次从队列中取出消息并响应。这种消息机制,就是Windows程序的运行机制。(进队消息和不进队消息(直接发给应用程序))

窗口过程函数:(回调函数)处理消息

5.WinMain函数:Windows程序的入口点函数。

      函数原型:int WINAPI WinMain(

                      HINSTANCE  hInstance,//程序当前运行的实例句柄(标识实例)

                      HINSTANCE  hprevInstance,//当前实例的前一实例的句柄(NULL)

                        LPSTR    lpCmdLine,//命令行参数

                         int     nCmdShow//指定程序的窗口如何显示

)//这四个参数都是系统调用WinMain函数时传递给应用程序的(实例句柄由操作系统分配)

6.窗口的创建

     (1)设计一个窗口类

          typedef struct _WNDCLASS{

                 UINT    style; //窗口样式(eg:CS_HREDRAW 水平重绘)位标志标识符

                WNDPROC  lpfnWndProc;//函数指针,指向窗口过程函数(回调函数)

                  int    cbClsExtra;//WNDCLASS类附加内存(0)

                  int    cbWndExtra;//窗口附加内存(0)

                 HANDLE  hInstance;//包含窗口过程的程序的实例句柄

                 HICON   hIcon;   //图标句柄(NULL为默认图标;LoadIcon()加载图标)

                HCURSOR  hCursor;//光标句柄(LoadCursor()加载光标)

                 HBRUSH  hbrBackground; //背景画刷句柄(GetStockObject()得到画刷)

                LPCTSTR  lpszMenuName; //指定菜单资源的名字(NULL,没有默认菜单)

                LPCTSTR  lpszClassName;//指定该窗口类的名字

} WNDCLASS;

         HICON LoadIcon(HINSTANCE hInstance;LPCTSTR lpIconName);//加载图标资源

         HCURSOR LoadCursor (HINSTANCE hInstance;LPCTSTR lpIconName);//加载光标

         HGDIOBJ GetStockObject(int fnObject);//得到系统的标准画刷

     (2)注册窗口

          ATOM RegisterClass(CONST WNDCLASS *lpWndClass);// lpWndClass:窗口类对象的指针.(注册成功后才可以创建该类型的窗口)

     (3)创建窗口

          HWND CreatWindow(

               LPCTSTR  lpClassName,//指定窗口类的名称即WNDCLASS. lpszClassName

               LPCTSTR  lpWindowName,//指定窗口的名称(显示在标题栏)

               DWORD    dwStyle,//指定创建的窗口的样式(eg:WS_OVERLAPPEDWINDOW位标志标识符)Todo: WNDCLASS的style是指定窗口类的样式,所有基于该窗口类创建的窗口都具有这些样式,而dwStyle是指定具体某个具体窗口的样式。

               int       x,//窗口左上角x坐标(CW_USEDEFAULT 默认位置,y被忽略)

               int       y,//窗口左上角y坐标

               int       nWidth,//窗口宽度(CW_USEDEFAULT 默认大小,nHeight忽略)

               int       nHeight,//窗口的高度

               HWND      hWndParent,//指定该窗口的父窗口的句柄

               HMENU     hMenu,//指定窗口菜单的句柄

               HANDLE    hInstance,//指定窗口所属的应用程序实例的句柄

               LPVOID    lpParam//WM_CREATE附加参数lParam传入的数据指针(NULL)

);

     (4)显示窗口

          BOOL ShowWindow(

               HWND   hWnd,   //窗口句柄

               Int    nCmdShow //指定窗口显示的状态

);

     (5)更新窗口

          BOOL UpdateWindow(HWND hWnd); //发送一个WM_PAINT消息来刷新窗口(直接发给窗口过程函数处理,不进入消息队列!)

7.消息循环

     (1)取出消息

           BOOL GetMessage(

                   LPMSG  lpMsg,//指向一个消息结构体(保存从消息队列中得到的消息)

                   HWND   hWnd,//指定接受哪一个窗口的消息(NULL,所有窗口)

                   UINT   wMsgFilterMin;//指定要获取的消息的最小值(0)

                   UINT   wMsgFilterMax//指定要获取的消息的最大值(0,所有消息)

);//接收到WM_QUIT消息时返回0值,其余非零,错误返回-1

     (2)转换消息

TranslateMessage(LPMSG  lpMsg);//将虚拟键消息转换为字符消息。

     (3)传递消息

DispatchMessage(LPMSG  lpMsg);//分派一个消息到窗口过程(实际上是将消息回传给操作系统,由操作系统调用窗口过程函数对消息进行处理)

     Todo:从消息队列中获取消息还可以使用PeekMessage()函数;发送消息可以使用SendMessage()和PostMessage()函数。其中,SendMessage()发送的是不进队消息,目标窗口将消息处理完毕后该函数才返回。还有PostThreadMessage()用于向线程发消息。

8.窗口过程函数

      LRESULT CALLBACK WindowProc(

             HWND    hWnd,//窗口句柄

             UINT    uMsg,//消息代码

             WPARAM  wParam,//附加参数

             LPARAM  lParam//附加参数

);

实例:第一个Windows窗口程序

#include<windows.h>

#include<stdio.h>

#include<string>

using namespace std;

 

LRESULT CALLBACK WindowProc(

             HWND    hWnd,  //窗口句柄

             UINT    uMsg,  //消息代码

             WPARAM  wParam,//附加参数

             LPARAM  lParam //附加参数

);//回调函数申明

 

int WINAPI WinMain(

      HINSTANCE  hInstance, //程序当前运行的实例句柄(标识实例)

      HINSTANCE  hprevInstance,//当前实例的前一实例的句柄(NULL)

      LPSTR    lpCmdLine, //命令行参数

      int     nCmdShow //指定程序的窗口如何显示

)

{

    //1.设计一个窗口类

    WNDCLASS wndClass;

    wndClass.cbClsExtra=0;//WNDCLASS类附加内存

    wndClass.cbWndExtra=0;//窗口附加内存

    wndClass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);//背景画刷句柄

    wndClass.hCursor=LoadCursor(NULL,IDC_ARROW);//光标句柄

    wndClass.hIcon=LoadIcon(NULL,IDI_INFORMATION);//图标句柄

    wndClass.hInstance=hInstance;   //应用程序实例句柄由WinMain函数传进来

    wndClass.lpfnWndProc=WindowProc;//函数指针,指向窗口过程函数(回调函数)

    wndClass.lpszClassName="FirstWin";//指定该窗口类的名字

    wndClass.lpszMenuName=NULL;//指定菜单资源的名字(NULL,没有默认菜单)

    wndClass.style=CS_HREDRAW|CS_VREDRAW;//窗口样式

 

    //2.注册窗口

    RegisterClass(&wndClass);

 

    //3.创建窗口

    HWND hwnd;  //定义一个变量用来保存成功创建窗口后返回的句柄

    hwnd=CreateWindow("FirstWin","MyFirstWin",WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL);

 

    //4.显示窗口

    ShowWindow(hwnd,SW_SHOWNORMAL);

 

    //5.更新窗口

    UpdateWindow(hwnd);

 

    //6.定义消息结构体,开始消息循环

    MSG msg;

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

    {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }

    return msg.wParam;

}

 

 

LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)//窗口过程定义

{

    switch(uMsg)

    {

    case WM_CHAR:    //用户按下字符键,程序将得到一个WM_CHAR消息,在其wParam中含有字符的ASCLL码值

         char szChar[20];

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

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

    /*函数原型:int MessageBox(

                      HWND hWnd,          // handle of owner window

                      LPCTSTR lpText,     // address of text in message box

                      LPCTSTR lpCaption,  // address of title of message box

                      UINT uType          // style of message box

);*/

 

         break;

    case WM_LBUTTONDOWN:

         MessageBox(hwnd,"mouse click!","message",0);

         HDC hdc;

         hdc=GetDC(hwnd);  //获取DC句柄(Device Context)

         TextOut(hdc,0,50,"My Process!",strlen("My Process!"));

   /*函数原型:BOOL TextOut(

                    HDC hdc,           // handle to device context

                    int nXStart,       // x-coordinate of starting position

                    int nYStart,       // y-coordinate of starting position

                    LPCTSTR lpString,  // pointer to string

                    int cbString       // number of characters in string

);*/

         ReleaseDC(hwnd,hdc);//用完后释放DC所占的资源,以免内存泄漏

         break;

    case WM_PAINT:

         HDC hDC;   //如果这里定义HDC hdc将和上一个case中定义重复,所以每个case中的变量不是仅在那个case中可见

         PAINTSTRUCT ps;//该结构体对象用于接受绘制的信息

         hDC=BeginPaint(hwnd,&ps);//调用BeginPaint函数得到DC句柄(在响应WM_PAINT消息时,要得到窗口的DC必须用BeginPaint函数

                                  //该函数也只能在响应WM_PAINT消息的代码中使用,在其他地方只能用GetDC来得到DC的句柄)

         TextOut(hDC,0,0,"My First Process!",strlen("My First Process!"));

         EndPaint(hwnd,&ps);//用BeginPaint函数得到的DC,必须用EndPaint函数释放

         break;

    case WM_CLOSE:

         if(IDYES==MessageBox(hwnd,"是否真的结束?","message",MB_YESNO))

         {

             DestroyWindow(hwnd);//DestroyWindow函数在销毁窗口后会向窗口过程发送WM_DESTROY消息,此时窗口已经销毁但程序还未退出

         }

         break;

    case WM_DESTROY:

        PostQuitMessage(0); //该函数向应用程序的消息队列中投递一条WM_QUIT消息并返回;GetMessage函数只有收到WM_QUIT消息才返回0,退出循环

        break;

    default: return DefWindowProc(hwnd,uMsg,wParam,lParam);//缺省的窗口过程

    }

    return 0;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值