zoukankan      html  css  js  c++  java
  • Windows SDK编程初探

    第一章 Windows程序的框架

    要点:程序的主函数,消息处理函数

          Windows程序具有相对稳定的结构,也就是说Windows程序是有一定的框架的,程序员要做的事情就是用特定的内容来填充这个框架。

          Windows程序的主函数:这个函数就像我们学习C语言时程序的主函数main()的功能是一样的,他代表了程序的入口。但是这个函数看上去比main()似乎繁的多,如果是第一次看见这个函数肯定会感觉一头雾水,但是不要紧我们来看看这个函数各个参数的意义,(其实开始的时候完全可以不理会他们的意义)hInstance是本实例的句柄,句柄可以理解为操作系统管理使用我们的应用程序的别名,它跟指针类似但又不同于指针,它的意义只有操作系统知道,也就是说操作系统通过hInstance就可以找到我们现在的这个程序。hPrevInstance是前一个实例的句柄。szCmdLine:是命令行参数,iCmdShow是窗口的显示方式。现在我们没有必要清除每个参数的具体意义,在接下来的学习中我们用的最多的就是hInstance这个参数,但也不多,而且我们使用vc++时,无论有哪种程序生成方式这个函数一般都会自动生成。

    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)

          主函数是windows程序框架的主要部分,由于windows程序是基于消息处理的,所以消息处理函数也算作是程序框架的一部分。说到消息,我觉得从基本的c编程转到windows编程最难的一点可能就是理解windows消息机制,虽然说是机制但不必觉得高深莫测,其实很简单,举个例子来说吧:在一个应用程序中有一个按钮,当按钮被按下时,我们已经习惯的程序会产生一个动作,在这样一个简单的过程中大部分事情是操作系统替我们完成了,检测按钮的动作,并将这个动作表现出来:按钮的按下、起来;按钮被按下时它会向他所在的程序发送一个消息“我被按下了”,程序中有一个消息处理函数,捕捉到这个消息,接着转而处理它:也就是调用相关的函数。

          那么我们就接着看一下消息处理函数,消息处理函数其实是一个消息循环,是一个回调函数,什么是回调函数暂不管它,只管理解为,函数由你定义而不归你调用,是由操作系统来调用的。下面来看一下,消息处理函数的原型及其结构:

    LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)

    {

       switch(message)

          {

             case...

             case...//这些分支语句用来分别处理不同的消息

          }

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

    /*这个函数是系统默认的消息处理函数,也就是说,我们的窗口程序的消息处理函数处理的只是我们感兴趣的消息,即上面的case语句,对于其他的消息我们还是使用系统默认的消息处理函数。我们的消息处理函数是要在我们的窗口主程序中登记的,登记为我们自定义的消息处理函数之后,系统的消息就有它来处理了。所以,在本函数的最后要使用该默认函数,否则其他的消息,本程序就无法处理了。*/

    }

       了解了消息处理函数,我们继续来看程序的主函数,它是程序的容器,程序的主窗体要在其中建立,程序的消息处理函数也要在其中设置。在主体函数中我们要做的就是两件事,一件是注册窗口类,另外一件是建立窗口。所谓注册窗口类就是通过填写一个WNDCLASS结构,我们的窗口就算基本成型,然后要向系统注册(注册过程系统也提供了相应的函数,当然技术差不多了以后也可以自己写注册过程)。窗口注册完毕,接下来的任务就是真正的来建立这个窗口,建立的时候前面注册的窗口类的名称作为参数传入,当然该窗口有自定义的消息处理函数的话,这时也要将这个函数传入。

             这样,我们就了解了Windows程序的框架,现在我再给出一个比较经典的Windows SDK程序的例子来看看我们的框架。

    //example.cpp

    #include //一定要包含该头文件

    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);//消息处理函数的声明,定义放在主函数后面

    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)

    {

       static TCHAR szAppName[]=TEXT("Hello");//注册的窗口类的名称,此处为"Hello"

       WNDCLASS wndclass;//定义了一个窗口类

       wndclass.style=CS_HREDRAW|CS_VREDRAW;

       wndclass.lpfnWndProc=WndProc;//此处关联了定义的消息处理函数

       wndclass.cbClsExtra=0;

       wndclass.cbWndExtra=0;

       wndclass.hInstance=hInstance;//实例句柄

       wndclass.hIcon=NULL;//窗口的图标,我们这里不设置

       wndclass.hCursor=LoadCursor(NULL,IDC_ARROR);//设置光标

       wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);//画刷

       wndclass.lpszMenuName=NULL;

       wndclass.lpszClassName=szAppName;//类名称

       if(!RegisterClass(&wndclass))//注册窗口

          {

             MessageBox(NULL,TEXT("窗口注册失败"),szAppName,MB_ICONERROR);

             return 0;

          }

       //下面开始建立窗口

       HWND hwnd;

       hwnd=CreateWindow(szAppName,TEXT("The Hello Program"),

                                           CW_OVERLAPPEDWINDOW,

                                           CW_USEDEFAULT,

                                            CW_USEDEFAULT,

                                           CW_USEDEFAULT,

                                           CW_USEDEFAULT,

                                           NULL,

                                           hInstance,

                                           NULL);

       ShowWindow(hwnd,iCmdShow);

       UpdateWindow(hwnd);

       //接下来是消息循环,程序不断的从消息队列中取消息,让消息处理函数处理

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

       {

          TranslateMessage(&msg);

          DispatchMessage(&msg);

       }

       return msg.wParam;

    }

    //消息处理函数定义

    LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM)//此例子中我们只是处理简单的消息

    {

       switch(message)

       {

          case WM_DESTROY:

                PostQuitMessage(0);

                return 0;

       }

       return ::DefWindowProc(hwnd,message,wParam,lParam);

    }

    to be continued...



    Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=30234

  • 相关阅读:
    BZOJ1527 : [POI2005]Pun-point
    2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
    2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
    NAIPC-2016
    BZOJ2498 : Xavier is Learning to Count
    ACM ICPC Vietnam National Second Round
    XVI Open Cup named after E.V. Pankratiev. GP of Ukraine
    XVI Open Cup named after E.V. Pankratiev. GP of Peterhof
    HDU5509 : Pattern String
    BZOJ4583 : 购物
  • 原文地址:https://www.cnblogs.com/draeag/p/898749.html
Copyright © 2011-2022 走看看