兰陵月 发表于 2016-10-9 11:35:08

【win32汇编】【罗云彬书】FirstWindow例子—回调函数_ProcWinMain

【win32汇编】【罗云彬书】FirstWindow例子—回调函数_ProcWinMain

例子里有一个回调函数(窗口过程)_ProcWinMain

其中该函数有四个参数:hWnd,uMsg,wParam,lParam

我的理解如下:

GetMessage后,返回获取了的消息队列中的消息的地址@stMsg,该地址指向一个MSG结构的消息数据。

经过DispatchMessage后,系统调用回调函数_ProcWinMain处理这些消息。

回调函数_ProcWinMain的参数中,hWnd,wParam,lParam都来自@stMsg指向的MSG结构的消息(此行的理解是否正确?)。

但是这个uMsg参数来自哪里?网上搜索一下,说是来自系统传过来的,但是说的不清不楚,我相信它是系统传过来的,请高手帮忙解答。

uMsg有什么用处?是什么类型的数据,它在哪里进行了定义,系统是什么时候给它赋值了?

刚刚开始学习,觉得好难,估计要学5遍以上才可能有初步理解。

麻烦您给我详细说一说~有涉及其他知识的,也麻烦简单提示下,谢谢

康小泡 发表于 2016-10-9 11:35:09

操作系统将每个事件都包装成一个消息结构体MSG来传递给应用程序,所以你提到的hWnd,wParam,lParam这三个参数都是来自MSG结构体。
MSG结构体
typedef struct tagMSG{
            HWND hwnd;窗口句柄(索引内存当中的资源)
            UINT(无符号整型)message;
            WPARAM(整型) wParam; //关于消息的附加参数,例如:按下一个键,具体是哪个按键
            LPARAM(整型) LParam; //关于消息的附加参数
            DWORD(32位整数) time;//消息被传递时候的时间
            POINT(坐标结构体) pt; //消息被传递时候,光标在屏幕上的位置
} MSG;


然后你说的那个umsg就是结构体重的第二个参数,UNIT message .这些消息都是来自己的触发的消息,比如你点击一下鼠标,应用程序接到消息后,然后它会把消息通过DispatchMessage(&msg)传递给窗口函数wndproc(也就是说的回调函数),窗口函数就会对照事先由程序编写好的消息对照表调用对应的方法来处理消息。

这个是我的理解,如果有错,我们再讨论

兰陵月 发表于 2016-10-9 11:36:16

按错了,标记成解决了~版主能否帮我改回来~

兰陵月 发表于 2016-10-9 11:37:47

@~风介~ @康小泡 @西电图图 @jun @人造人 @不二如是

不二如是 发表于 2016-10-9 11:55:49

我不是这‘峰’的,能力所限,办不到{:10_266:}

不行重新发一个

兰陵月 发表于 2016-10-9 13:14:56

康小泡 发表于 2016-10-9 12:20
操作系统将每个事件都包装成一个消息结构体MSG来传递给应用程序,所以你提到的hWnd,wParam,lParam这三个参 ...

是我错了,我纠结于名称的一致。
联想到C语言的参数传递方式,恍然大悟。

uMsg即message,message即uMsg
{:10_262:}

人造人 发表于 2016-10-9 23:34:16

把你想知道的值打印出来看一看不就知道了
/* -------------------------------------------------------------------
                  MyWindows.c -- 基本窗口模型
                                《Windows 程序设计(SDK)》视频教程                  
--------------------------------------------------------------------*/

#include <windows.h>
#include <strsafe.h>

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

TCHAR str_buf;
int str_buf_cnt = 0; // 统计str_buf的元素个数
int current_location = 0; // 字符串在str_buf中的当前位置
int str_len = 0; // 字符串长度

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
        static TCHAR szAppName[] = TEXT("MyWindows");
        HWND hwnd;
        MSG msg;
        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 = szAppName;

        if (!RegisterClass(&wndclass))
        {
                MessageBox(NULL, TEXT("这个程序需要在 Windows NT 才能执行!"), szAppName, MB_ICONERROR);
                return 0;
        }

        hwnd = CreateWindow(szAppName,
                TEXT("鱼C工作室"),
                WS_OVERLAPPEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                NULL,
                NULL,
                hInstance,
                NULL);
       
        StringCchPrintf(&str_buf, 512, L"(%d)WinMain函数中的hwnd是:%d\n", str_buf_cnt++, hwnd);
        StringCchLength(&str_buf, 512, &str_len);
        current_location += str_len;

        ShowWindow(hwnd, iCmdShow);
        UpdateWindow(hwnd);

        while (GetMessage(&msg, NULL, 0, 0))
        {
                StringCchPrintf(&str_buf, 512, L"(%d)WinMain函数中的msg是:%d\n", str_buf_cnt++, msg);
                StringCchLength(&str_buf, 512, &str_len);
                current_location += str_len;

                StringCchPrintf(&str_buf, 512, L"(%d)WinMain函数中的msg中的hwnd是:%d\n", str_buf_cnt++, msg.hwnd);
                StringCchLength(&str_buf, 512, &str_len);
                current_location += str_len;

                TranslateMessage(&msg);
                DispatchMessage(&msg);
        }

        return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;
       

       
        StringCchPrintf(&str_buf, 512, L"(%d)WndProc函数中的hwnd是:%d\n", str_buf_cnt++, hwnd);
        StringCchLength(&str_buf, 512, &str_len);
        current_location += str_len;
       

        if(str_buf_cnt >= 60) // 小心数组越界
        {
                HANDLE hFile = CreateFile(L"text.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
               
                //WriteFile(hFile, str_buf, 2048, NULL, NULL); // 这样不行,打开test.txt文件乱码
                for(int i = 0; i < 2048; i++)
                {
                        if((*(UINT16 *)(&str_buf) & 0xff00) == 0)
                        {
                                WriteFile(hFile, &str_buf, 1, NULL, NULL);
                        }
                        else
                        {
                                WriteFile(hFile, &str_buf, 2, NULL, NULL);
                        }
                       
                }
               
                CloseHandle(hFile);

                ExitProcess(0);

        }

        switch (message)
        {
        case WM_PAINT:
                hdc = BeginPaint(hwnd, &ps);
                GetClientRect(hwnd, &rect);
                DrawText(hdc, TEXT("大家好,这是我的第一个窗口程序!"), -1, &rect,
                        DT_SINGLELINE | DT_CENTER | DT_VCENTER);
                EndPaint(hwnd, &ps);
                return 0;

        case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
        }

        return DefWindowProc(hwnd, message, wParam, lParam);
}
这是我运行的一次结果

文件因为编码问题,出现了乱码,不过能看出想要的结果就行了

(0)WndProc齉pe-N剉hwnd/f

人造人 发表于 2016-10-9 23:42:50

我复制notepad++中的乱码,这里也乱码了?
我后面写的内容也没了?
那我再写一次吧。

可以看出
WndProc函数中的hwnd是WinMain中CreateWindow的返回值
msg的值和msg中的hwnd的值在运行中发生了改变

人造人 发表于 2016-10-9 23:45:56

加张图片吧

兰陵月 发表于 2016-10-10 08:14:11

我仔细看看~
页: [1]
查看完整版本: 【win32汇编】【罗云彬书】FirstWindow例子—回调函数_ProcWinMain