zoukankan      html  css  js  c++  java
  • 消息处理函数的返回值

    刚刚开始学习 windows 编程,就遇到一件比较尴尬的事。学着孙鑫老师的例子,马马虎虎搭了一个框。没想到最后的地方落了一句:在消息处理函数中,对于默认消息的处理,本应该这么写:

    default:
    return DefWindowProc(hWnd,message,wParam,lParam);

    不过我却写成了这样:

    default:
    DefWindowProc(hWnd,message,wParam,lParam);

    少了一个返回值,结果是窗口就显示不出来了。但是这个进程却开启了。

    为找到错误而松了一口气的同时,开始思索这到底是为什么。接下来写上自己的思考,并无结论,仅仅是脑海里的笔记而已,只为自己日后参考。企图寻找答案的同胞请赶紧另寻它途免得浪费时间;而已知其中奥秘的大神请不要吝啬写下你们的良方。谢谢。


    我理解一个windows程序的运行,会有四个部件参与:

    a. 应用程序主体。
    b. windows操作系统。
    c. 一个关于本程序的消息队列。
    d. 一个关于本程序的消息处理函数。

    a.应用程序主体负责构建窗口类,并注册它,创建对应窗口,然后令其显示更新。接下来就进入消息循环主体,在这里进行轮复一轮的运转,直到有退出消息使其解脱。

    b. windows操作系统负责从c. (一个关于本程序的消息列表) 中提取消息。然而事实上它不是第一提取人。应用程序主体才是。因为应用程序主体中有GetMessage(&msg,NULL,0,0)函数,它将消息队列提取到msg结构体中。消息队列在哪里?它对我们不可见,我们不知道它在哪里。但却总能通过msg来获悉消息。接下来,应用程序调用函数TranslateMessage(&msg)做了一些翻译,不必知道细节,因为不影响结果。再然后,应用程序调用DispatchMessage(&msg)把消息传递给了windows,可以说这个时侯,windows才开始接管该消息,而且window也开始介入该应用程序,接手其控制权。那么DispatchMessage(&msg)做了什么?网上查了一下,它把该消息发给了d. ( 一个关于本程序的消息处理函数) 。而且只有当消息处理函数返回后,它才返回。也就是说,消息处理函数的运作,是包含在DispatchMessage(&msg)这一步里的。

    c.关于本程序的消息队列,对程序员透明。至少目前对我来说透明。

    d.消息处理函数,由应用程序编写,但却由操作系统调用。孙鑫老师比喻的好,应用程序好比一家汽车生产厂家,windows好比顾客,而消息处理函数好比对应汽车品牌的修理厂家。汽车生产商不负责修理汽车,但却会为顾客指定一家修理商。以后汽车坏了,不必找生产商,而是直接找修理商。不过这个比喻虽然生动,细想还是不太妥当。因为程序毕竟不是汽车生产商,程序可以直接负责传递消息给自己,然后再自己处理,这种情况不是实现不了,但为何中间一定要通过windows来插这一脚呢?想必一定有它的道理,我认为这中间的原委深刻而合理,所以也不怀疑。

    根据以上的分析,再来思考为什么没有return就显示不了窗口。我在想为什么需要消息处理函数需要返回值?既然有返回值,那应该是用来判断这条消息处理成功了没有。它的返回值带有处理结果的某种信息。操作系统根据该信息来做下一步的部署。比如,如果处理成功了,那么应该把控制权交回给应用程序,这时应用程序会接着从消息队列里取出下一条消息;如果没成功,那么可能(我不知道,猜的)windows会等待其响应直到处理完毕得到结果。这样的话,因为我的程序里没有写上这个return,因此windows就永远也不知道消息处理得怎么样了,它将会一直等待在这里。这时程序就卡住了。

    又想了想感觉是在胡扯,因为发现,这么写程序照样运转的很好:

    switch(uMsg)
        {

        case WM_PAINT:
            HDC hDC;
            PAINTSTRUCT ps;
            hDC=BeginPaint(hwnd,&ps);
            EndPaint(hwnd,&ps);
            break;

        case WM_CLOSE:
            if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO))
            {
                DestroyWindow(hwnd);
            }
            break;

        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hwnd,uMsg,wParam,lParam);
        }

        //return 0;  去掉这个返回值 
    }

    当产生WM_PAINT、 WM_CLOSE、 WM_DESTROY这样的消息时,程序应该不会返回值了吧,但还能运转。Jesus Christ.



  • 相关阅读:
    卧槽!缓存的问题太多了(雪崩、击穿、穿透…)一个个解决!
    Java 命名规范(非常全面,可以收藏)
    一次接口超时排查,花费了我两个星期。。
    LiveGBS和海康威视
    SQLite文件存储和读取
    Vue页面刷新原理:Cesium刷新机制
    MBtiles格式数据
    gitee:403错误
    uniapp是什么?
    HBuilderx怎么运行代码
  • 原文地址:https://www.cnblogs.com/lookof/p/1420151.html
Copyright © 2011-2022 走看看