模板程序详解

来源:互联网 发布:学生水乳推荐 知乎 编辑:程序博客网 时间:2024/06/06 00:07

我想大部分同学在学校学习c语言时都使用vc6.0,新建一个c++ source file。在windows编程时,你需要创建一个windows 32 Application空项目,然后再向里面添加头文件和源文件。而且编译器最好新一些,我用的是vs2010。好了,接下来开始解读这个程序。

首先你要明白这个程序的功能,它会产生一个窗口,并播放一个wav格式的音乐,前提是你的电脑上有这个音乐。


我想最主要困扰大家的应该是那一串没见过的数据类型,什么TCHAR,HWND,MSG。这个不要担心,我会专门发一张表的。其实你也可以在vc里右键单击转到定义。一般都是typedef 的c语言里的数据类型,还有一些结构体。不过HWND这个得好好讲讲,它是窗口句柄类型。什么是句柄呢?就是一串用来标记的数字。用HWND定义句柄后,操作系统会给你的窗口一串唯一的数字,绝对不会和其它的窗口一样,这样你调用的时候会很方便,当然操作系统调用更方便。形象点说,就相当于身份证号。系统可以通过身份证号快速的找到你。其它有不懂的可以在下面问我。


int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,

   PSTR szCmdLine,int iCmdShow)

看起来很长,其实你也不用记住它,需要的时候复制过去就是了,它就相当与c语言编程时的main()。windows编程时WinMain()就是主函数。

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);是一个函数声明,这个是什么函数呢? CALLBACK是什么意思?在winmain()中为什么找不到调用它的地方?好了,我来一一解答。它是窗口过程函数, CALLBACK是说它是一个回调函数。什么是回调函数呢,就是由操作系统调用,而不是编程者自己调用的函数,这也就是为什么在主函数中调用它的原因。

这里我要阐述一个关键点,在windows编程时,主函数反而是最不重要的。为什么呢,因为基本是所有的主函数都是一样的,重要的反而是 WndProc函数。我将模板程序的主函数中的代码封装一下,这样好讲一点。主要封装成下面两个函数。

ATOM MyRegisterClass(HINSTANCE hInstance)  

{  

    WNDCLASSEX wcex;  

  

    wcex.cbSize = sizeof(WNDCLASSEX);   

    wcex.style          = CS_HREDRAW | CS_VREDRAW;  

    wcex.lpfnWndProc    = (WNDPROC)WndProc;  

    wcex.cbClsExtra     = 0;  

    wcex.cbWndExtra     = 0;  

    wcex.hInstance      = hInstance;  

    wcex.hIcon          = NULL;  

    wcex.hCursor        = NULL;  

    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);  

    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);  

    wcex.lpszMenuName   = NULL;  

    wcex.lpszClassName  = szAppName;  

    wcex.hIconSm        = NULL;  

  

    return RegisterClassEx(&wcex);  

}  

  

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)  

{  

    HWND hWnd;  

    HDC hdc;  

  

    hInst = hInstance;  

  hWnd=CreateWindow(szAppName,//创建窗口

  TEXT("THIS IS THE WINDOW"),

  WS_OVERLAPPEDWINDOW,

  CW_USEDEFAULT,

   CW_USEDEFAULT,

                       CW_USEDEFAULT,

                     CW_USEDEFAULT,

 NULL,

 NULL,

 hInstance,

 NULL);

  

    if (!hWnd)  

    {  

        return FALSE;  

    }  

  

   

    ShowWindow(hWnd, nCmdShow);  

    UpdateWindow(hWnd);  

  

   

    return TRUE;  

}  


改造后的WinMain()如下

int APIENTRY WinMain(HINSTANCE hInstance,  

                     HINSTANCE hPrevInstance,  

                     LPSTR     lpCmdLine,  

                     int       nCmdShow)  

{  

    MSG msg;  

  static TCHAR szAppName[]=TEXT("nameofwindow");

    MyRegisterClass(hInstance);  

  

    if (!InitInstance (hInstance, nCmdShow))   

    {  

        return FALSE;  

    }  

  

    //消息循环  

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

    {  

        TranslateMessage(&msg);  

        DispatchMessage(&msg);  

    }  

      

    return msg.wParam;  

}  

可以看出,主函数干了三件事。注册窗口类,显示窗口,开启消息循环。先说注册窗口类,就像做填空题一样,拼出你想要的窗口,比如它的图标是什么样,背景是什么颜色等。窗口类的每一个选项是什么意思你可以去百度搜,我后面会发。窗口类注册好之后,就会按照注册窗口类时的选项产生窗口。CreateWindow自然就是产生窗口了,为什么它有那么多参数呢?因为它要对窗口类做进一步说明。比如窗口产生时的位置是在中间还是左上角。那为什么还要ShowWindow呢?因为前面窗口虽然已经产生,但它是在内存中,ShowWindow会把在内存中的窗口显示到屏幕。接下来UpdateWindow是干什么的呢?我们可以改变窗口的位置,大小,如果不刷新一下是看不到窗口位置,大小的改变的。所以这是为了在窗口改变时刷新用的。回到主函数,我标明消息循环的部分是干什么的呢?

这里我就要说一下windows 的 消息驱动机制了。简单说就是 “消息---事件”。比如你点一下关机按钮,系统就会关机。这里你点按钮时实际上是在给系统一个“关机”的命令,也就是消息。系统的反应(也就是事件)就是关机。

GetMessage是从操作系统那得到消息,TranslateMessage自然是翻译消息了,DispatchMessage是派发消息,发给谁呢,就是WndProc()函数。主函数和窗口过程函数就是这样联系到一起的。return msg.wParam的作用和c语言return 0是一个道理。

好了,关于窗口过程函数我会在下一节讲。这个程序很长,涉及到的知识点很多。但千万不要认为windows编程有多难,我敢说,只要掌握了这个程序,后面的学习非常简单。