Win32 Application Hello World 详细注释

    // win32project.cpp : Defines the entry point for the application.  
    //  

    #include "stdafx.h"  
    #include "win32project.h"  

    #define MAX_LOADSTRING 100  

    // Global Variables:  
    HINSTANCE hInst;                                // current instance  
    TCHAR szTitle[MAX_LOADSTRING];                  // The title bar text  
    TCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name  

    // Forward declarations of functions included in this code module:  
    ATOM                MyRegisterClass(HINSTANCE hInstance);  
    BOOL                InitInstance(HINSTANCE, int);  
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);  
    INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);  

    int APIENTRY _tWinMain(HINSTANCE hInstance,//当前实例句柄  
                         HINSTANCE hPrevInstance,//NULL,为了兼容  
                         LPTSTR    lpCmdLine,//该字符串包含传递给应用程序的命令行参数  
                         int       nCmdShow)//指定程序的窗口应该如何显示  
    {  
        UNREFERENCED_PARAMETER(hPrevInstance);  
        UNREFERENCED_PARAMETER(lpCmdLine);  

        // TODO: Place code here.  
        MSG msg;  
        HACCEL hAccelTable;  

        // Initialize global strings  
        LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);  //将szTitle赋值为字符串IDS_APP_TITLE  
        LoadString(hInstance, IDC_WIN32PROJECT, szWindowClass, MAX_LOADSTRING); //将szWindowClass赋值为字符串IDC_WIN32PROJECT  
        MyRegisterClass(hInstance);  

        // Perform application initialization:  
        if (!InitInstance (hInstance, nCmdShow))  
        {  
            return FALSE;  
        }  

        hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WIN32PROJECT));  

        // Main message loop:  
        while (GetMessage(&msg, NULL, 0, 0))    //编写消息循环代码  
        {  
            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))  
            {  
                TranslateMessage(&msg); //请求Windows为那些与键盘有关的消息做一些转换工作  
                DispatchMessage(&msg);  //请求Windows分派消息到窗口过程,由窗口过程函数对消息进行处理  
            }  
        }  

        return (int) msg.wParam;  
    }  



    //  
    //  FUNCTION: MyRegisterClass()  
    //  
    //  PURPOSE: Registers the window class.  
    //  
    //  COMMENTS:  
    //  
    //    This function and its usage are only necessary if you want this code  
    //    to be compatible with Win32 systems prior to the 'RegisterClassEx'  
    //    function that was added to Windows 95. It is important to call this function  
    //    so that the application will get 'well formed' small icons associated  
    //    with it.  
    //  
    ATOM MyRegisterClass(HINSTANCE hInstance)   //设计窗口类  
    {  
        WNDCLASSEX wcex;    //创建WNDCLASSEX类型的对象  

        wcex.cbSize = sizeof(WNDCLASSEX);  

        wcex.style          = CS_HREDRAW | CS_VREDRAW;  //设置窗口的样式  
        wcex.lpfnWndProc    = WndProc;                  //回调函数  
        wcex.cbClsExtra     = 0;                        //可以请求额外空间,一般不需要  
        wcex.cbWndExtra     = 0;  
        wcex.hInstance      = hInstance;                //指定当前应用程序的实例句柄  
        wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT));//指定窗口类的图标句柄  
        wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);  //指定窗口类的光标句柄  
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);     //指定窗口类的背景画刷句柄  
        //wcex.hbrBackground = static_cast<HBRUSH>(GetStockObject(BLACK_BRUSH));  //BLACK_BRUSH,DKGRAY_BRUSH, GRAY_BRUSH  
        wcex.lpszMenuName   = MAKEINTRESOURCE(IDC_WIN32PROJECT);//lpszMenuName是一个以空终止的字符串,指定菜单资源的名字。  
                                                                //如果该窗口没有菜单,则应该将其设为0.  
        wcex.lpszClassName  = szWindowClass;                    //指定窗口类的名字  
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); //标识某个窗口最小化时显示的图标  

        return RegisterClassEx(&wcex);//调用RegisterClassEx()函数向系统注册窗口类  
    }  

    //  
    //   FUNCTION: InitInstance(HINSTANCE, int)  
    //  
    //   PURPOSE: Saves instance handle and creates main window  
    //  
    //   COMMENTS:  
    //  
    //        In this function, we save the instance handle in a global variable and  
    //        create and display the main program window.  
    //  
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)  
    {  
       HWND hWnd;  

       hInst = hInstance; // Store instance handle in our global variable  
       //创建窗口  
       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,  
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);  

       if (!hWnd)  
       {  
          return FALSE;  
       }  

       ShowWindow(hWnd, nCmdShow);  //初始化窗口  
       UpdateWindow(hWnd);  //通知Windows应用程序重绘客户区  

       return TRUE;  
    }  

    //  
    //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)  
    //  
    //  PURPOSE:  Processes messages for the main window.  
    //  
    //  WM_COMMAND  - process the application menu  
    //  WM_PAINT    - Paint the main window  
    //  WM_DESTROY  - post a quit message and return  
    //  
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) //窗口过程函数  
    {  
        int wmId, wmEvent;  
        PAINTSTRUCT ps;  
        HDC hdc;  

        switch (message)  
        {  
        case WM_COMMAND:  
            wmId    = LOWORD(wParam);  
            wmEvent = HIWORD(wParam);  
            // Parse the menu selections:  
            switch (wmId)  
            {  
            case IDM_ABOUT:  
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);  
                break;  
            case IDM_EXIT:  
                DestroyWindow(hWnd);  
                break;  
            default:  
                return DefWindowProc(hWnd, message, wParam, lParam);  
            }  
            break;  
        case WM_PAINT:  
            hdc = BeginPaint(hWnd, &ps);  
            // TODO: Add any drawing code here...  
            TextOut(hdc,100,100,L"Visual C++ 2010",sizeof("Visual C++ 2010")-1);  
            EndPaint(hWnd, &ps);  
            break;  
        case WM_DESTROY:  
            PostQuitMessage(0);  
            break;  
        case WM_LBUTTONDOWN:  
            MessageBox(hWnd, TEXT("单击鼠标左键"),TEXT("提示"),0);  
            break;  
        default:  
            return DefWindowProc(hWnd, message, wParam, lParam);  
        }  
        return 0;  
    }  

    // Message handler for about box.  
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)  
    {  
        UNREFERENCED_PARAMETER(lParam);  
        switch (message)  
        {  
        case WM_INITDIALOG:  
            return (INT_PTR)TRUE;  

        case WM_COMMAND:  
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)  
            {  
                EndDialog(hDlg, LOWORD(wParam));  
                return (INT_PTR)TRUE;  
            }  
            break;  
        }  
        return (INT_PTR)FALSE;  
    }  
Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->//一个简单的Win32应用程序

//通过这个简单的实例讲解Windows消息是如何传递的

#include "stdafx.h"
#include <windows.h>

//声明窗口过程函数
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

//定义一个全局变量,作为窗口类名
TCHAR szClassName[] = TEXT("SimpleWin32");

//应用程序主函数
int WINAPI WinMain (HINSTANCE hInstance,
                                  HINSTANCE hPrevInstance,
                                  LPSTR szCmdLine,
                                  int iCmdShow)
{

    //窗口类
    WNDCLASS wndclass;

    //当窗口水平方向的宽度和垂直方向的高度变化时重绘整个窗口
    wndclass.style = CS_HREDRAW|CS_VREDRAW;

    //关联窗口过程函数
    wndclass.lpfnWndProc = WndProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = 0;
    wndclass.hInstance = hInstance;//实例句柄
    wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);//图标
    wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);//光标
    wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//画刷
    wndclass.lpszMenuName  = NULL;//菜单
    wndclass.lpszClassName = szClassName;//类名称

    //注册窗口类
    if(!RegisterClass (&wndclass))
    {
           MessageBox (NULL, TEXT ("RegisterClass Fail!"), 
                   szClassName, MB_ICONERROR);
           return 0;
    }



    //建立窗口
    HWND hwnd;
    hwnd = CreateWindow(szClassName,//窗口类名称
           TEXT ("The Simple Win32 Application"),//窗口标题 
           WS_OVERLAPPEDWINDOW,//窗口风格,即通常我们使用的windows窗口样式
           CW_USEDEFAULT,//指定窗口的初始水平位置,即屏幕坐标系的窗口的左上角的X坐标
           CW_USEDEFAULT,//指定窗口的初始垂直位置,即屏幕坐标系的窗口的左上角的Y坐标
           CW_USEDEFAULT,//窗口的宽度
           CW_USEDEFAULT,//窗口的高度
           NULL,//父窗口句柄
           NULL,//窗口菜单句柄
           hInstance,//实例句柄
           NULL);

    ShowWindow(hwnd,iCmdShow);//显示窗口
    UpdateWindow(hwnd);//立即显示窗口



    //消息循环
    MSG msg;

    /*
    GetMessage()从消息队列中取消息,对取出的消息进行转换(TranslateMessage),
    对于能够将虚拟键码转化成字符码的消息,会在消息队列里放一条WM_CHAR消息,
    最后将消息发送到相应的消息处理函数进行处理。
    循环执行这个处理过程,直到收到WM_QUIT消息,才退出循环,结束程序。
    */
    while(GetMessage(&msg,0,0,0))//从消息队列中取消息 
    {
           TranslateMessage (&msg);              //转换消息
           DispatchMessage (&msg);               //派发消息
    }
    return msg.wParam;
    /*---------------GetMessage---------------------------------
    GetMessage

    函数原型:
    BOOL GetMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax);

    参数:
    lpMsg:一个指向MSG结构的指针,该结构用于存放从消息队列里取出的消息。
    hWnd:窗口句柄。如果该参数是非零值,则GetMessage只检索该窗口(也包括其子窗口)消息,如果为零,则GetMessage检索整个进程内的消息。
    wMsgFilterMin:指定被检索的最小消息值,也就是消息范围的下界限参数。
    wMsgFilterMax:上界限参数。如果wMsgFilterMin和wMsgFilterMax都为零,则不进行消息过滤,GetMessage检索所有有效的消息。

    返回值:
    GetMessage检索到WM_QUIT消息,返回值是零;其它情况,返回非零值。

    函数功能:
    这个API函数用来从消息队列中“摘取”一个消息,放到lpMsg所指的变量里。(注:如果所取窗口的消息队列中没有消息,则程序会暂停在GetMessage(…) 函数里,不会返回。)
    再通俗一点讲解GetMessage函数:
    当程序执行GetMessage()的时候,会检查消息队列,如果有消息在消息队列里,它取出该消息,将该消息填充到lpMsg所指的MSG结构,并返回TRUE值。如果此时消息队列里没有消息(消息队列为空),它会将线程阻塞,也就是将控制权交给系统,直到消息队列中有内容时,才唤醒线程继续执行。
    对于GetMessage()函数,还有一点需要说明,就是当从消息队列中取出的消息是WM_QUIT时,函数返回值是0。我们一般利用这一点退出消息循环,结束程序。
    ---------------------------------------------------------------*/

    /*------------------TranslateMessage---------------------
    TranslateMessage 

    函数原型:

    BOOL TranslateMessage(CONST MSG*lpMsg);

    参数:
      IpMsg:指向MSG结构的指针,该结构是函数GetMessage或PeekMessage从消息队列里取得的消息。

     函数功能:
        该函数将虚拟键消息转换为字符消息。字符消息被寄送到调用线程的消息队列里,当下一次线程调用函数GetMessage或PeekMessage时被读出。
    什么是虚拟键码呢?Windows为了方便输入管理,减少程序对设备的依赖性,将键盘上所有的按键都用一个两位十六进制数对应,这些数称为虚拟键码。虚拟键码一般以VK_开头,如:Esc键对应的虚拟键码是VK_ESCAPE;空格键对应的虚拟键码是VK_SPACE;VK_LWIN与左边的Windows徽标键相对应。
    当一个按键被按下时,会触发WM_KEYDOWN消息, WM_KEYDOWN消息的wParam参数值就是虚拟键值。通过这个值就可以判断哪个键被按下了。
    为什么我们要把虚拟键码转换为字符码呢?
    比如我们按下了‘A’键,此时我们得到的字符可能是‘A’,也可能是小写的‘a’,这由当时的大写状态(Caps Lock)以及是否同时按下了Shift键有关。TranslateMessage()函数的作用就是不用我们考虑这些问题,而是根据这些情况,自动返回一个ASCII码值,以方便用户使用。
    并不是所有的虚拟键码值都会Translate成字符码。字母、数字键都有字符码相对应,而像方向箭头键、F1—F12功能键这些按键就没有字符码相对应。当虚拟键码需要转化成字符码时,TranslateMessage()函数就在消息队列里放一条WM_CHAR消息,WM_CHAR消息的wParam参数值就是转换后的ASCII码值。
    -------------------------------------------*/

    /*--------------------DispatchMessage-------------------
    DispatchMessage 

    函数原型:
    LONG DispatchMessage(CONST MSG *lpmsg);

    函数功能:
    它的作用很简单,就是分派消息到窗口的消息处理函数去执行。
    -------------------------------------------*/

    /*-----------------PeekMessage-------------
    PeekMessage

    函数原型:
    BOOL PeekMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);

    参数:
    lpMsg、hWnd、wMsgFilterMin、wMsgFilterMax这四个参数的意义和GetMessage对应参数的意义相同,在此不再赘述。
    wRemoveMsg:这个参数决定读消息时是否删除消息,可选值有PM_NOREMOVE和PM_REMOVE。如果您选PM_NOREMOVE,执行该函数后消息仍然留在消息队列(我称为读消息);如果您选PM_REMOVE,执行该函数后将在消息队列中移除该消息(同GetMessage())。

    返回值:
    消息队列中有消息,返回值为TRUE;消息队列中没有消息,返回值为FALSE。

    函数功能:
    PeekMessage()也是从消息队列中取消息,但它是GetMessage()不同,主要在以下两点:

    (一)、GetMessage()只能从消息队列中取走消息,也就是说,GetMessage()执行后,该消息将从消息队列中移除。
    PeekMessage()可以从消息队列中取走消息。也可以读消息,让消息继续留在消息队列里。

    (二)、当消息队列中没有消息时,GetMessage()将会阻塞线程,等待消息;而PeekMessage()与GetMessage()不同,它执行后会立刻返回,消息队列中有消息时,返回值为TRUE;消息队列中没有消息时,返回值为FALSE。

    ------------------------------------*/

    /*-------------------PeekMessage版的消息循环---------------------------
    //消息循环
    MSG msg;

    while(true)
    {
          if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) //从消息队列中取消息
          {
                  if(msg.message == WM_QUIT)
                        break;
                  TranslateMessage (&msg);           //转换消息
                  DispatchMessage (&msg);            //派发消息
           }
           else
                  WaitMessage();

    } //End of while(true)
    */

    /*------------------WaitMessage--------------------------
    WaitMessage

    函数原型:
    BOOL WaitMessage(VOID);

    函数功能:
    这个函数的作用是当消息队列中没有消息时,将控制权交给其它线程。该函数将会使线程挂起,直到消息队列中又有新消息。
    这个函数专门和PeekMessage配合使用,当消息队列中没有消息时,挂起线程,等待消息队列中新消息的到来,这样可以减轻CPU的运算负担。
    --------------------------------------------------*/
}

//消息处理函数

//参数:窗口句柄,消息,消息参数,消息参数

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    //处理感兴趣的消息
    switch (message)
    {
        case WM_DESTROY:
            //当用户关闭窗口,窗口销毁,程序需结束,发退出消息,以退出消息循环
            PostQuitMessage(0);
            return 0;
    }
    //其他消息交给由系统提供的缺省处理函数
    return ::DefWindowProc (hwnd, message, wParam, lParam);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值