计机羊咩咩 发表于 2014-8-4 21:50:15

论WM_PAINT消息不断发送的原因

呃这是我自己写的一个小程序当然还没写完而且出问题了
不要看着长就吓到了实际上就是WinMain和Proc两个函数而已
当然自己改编的地方是有注释的

问题是按钮(子窗口)的重定位导致WM_PAINT不断重复发送成了死循环
求大神解决下面是代码 有点长最后我会贴上问题区域的代码


#include<windows.h>
#include<strsafe.h>
LRESULT CALLBACK WndProc(HWND ,UINT ,WPARAM ,LPARAM );


int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
                                   PSTR szCmdLine,int iCmdShow)
{
        static TCHAR szAppName[] = TEXT("Hello fish");
        HWND hwnd;
        MSG msg;
        WNDCLASS wndclass;

        wndclass.cbClsExtra = 0;
        wndclass.cbWndExtra = 0;
        wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
        wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
        wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
        wndclass.hInstance = hInstance;
        wndclass.lpfnWndProc = WndProc;
        wndclass.lpszClassName = szAppName;
        wndclass.lpszMenuName = NULL;
        wndclass.style = CS_HREDRAW | CS_VREDRAW;

        if(!RegisterClass(&wndclass))
        {
                MessageBox(NULL,TEXT("require windows NT!"),
                        szAppName,MB_ICONERROR);
                return 0;
        }

        hwnd = CreateWindow(szAppName,
                TEXT("鱼C工作室"),
                WS_OVERLAPPEDWINDOW,
                //WS_POPUP,
                //WS_POPUP | WS_SIZEBOX,
                300,
                300,
                400,
                200,
                NULL,
                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 hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;
        HWND hButton;
        float fxLocation,fyLocation;

        static int iPaintAgain = 0;

        switch(message)
        {
        case WM_CREATE:
                hButton = CreateWindow(L"Button",L"random",WS_VISIBLE | WS_CHILD,
                        160,100,60,30,hwnd,NULL,NULL,NULL);
                return 0;

        case WM_PAINT:
                        hdc = BeginPaint(hwnd,&ps);
                        GetClientRect(hwnd,&rect);
                        if(0 == iPaintAgain)
                        {
                                DrawText(hdc,TEXT("嗨,我是一个窗口,主人刚刚把我做出来了。"),-1,&rect,
                                        DT_SINGLELINE | DT_CENTER | DT_VCENTER);
                        }
                        else if(0 < iPaintAgain)
                        {
                                TCHAR szPrintf;         //这个是字符缓冲区下面一个函数类似于printf当然是输出在szPrintf[]内
                                StringCchPrintf(szPrintf,15,L"噢,我被重绘了%d次",iPaintAgain);
                                DrawText(hdc,szPrintf,-1,&rect,
                                        DT_SINGLELINE | DT_CENTER | DT_VCENTER);

                                hButton = FindWindowEx(hwnd,NULL,L"Button",L"random");//获取子窗口
                                DestroyWindow(hButton);                                 //销毁子窗口
                                GetClientRect(hwnd,&rect);                              //获取客户区大小
                                fxLocation = (rect.right - 60) / 2;                     //计算客户区更新后按钮的x坐标
                                fyLocation = (float)(rect.bottom - 30) / 1.6;         //计算客户区更新后按钮的y坐标
                                hButton = CreateWindow(L"Button",L"random",WS_VISIBLE | WS_CHILD,
                                        (int)fxLocation,(int)fyLocation,60,30,hwnd,NULL,NULL,NULL);
                        }
                        EndPaint(hwnd,&ps);
                        iPaintAgain++;
                        return 0;

        caseWM_LBUTTONUP:
                if(0 == wParam)MessageBox(NULL,TEXT("按击来自主人的食指"),TEXT("小样的"),MB_OK);
                else MessageBox(NULL,TEXT("左右开弓,旗开得胜"),TEXT("小样的"),MB_OK);
                return 0;

        case WM_RBUTTONUP:
                if(0 == wParam)MessageBox(NULL,TEXT("感受到主人中指的力度"),TEXT("小样的"),MB_OK);
                else MessageBox(NULL,TEXT("左右开弓,旗开得胜"),TEXT("小样的"),MB_OK);
                return 0;

        case WM_DESTROY:
                PostQuitMessage(0);
                return 0;
        }
        return DefWindowProc(hwnd,message,wParam,lParam);
}



以上是完整的代码 下面是出问题的区域也是子窗口重定位的语句在这里的定位出问题了


else if(0 < iPaintAgain)
                        {
                                TCHAR szPrintf;         //这个是字符缓冲区下面一个函数类似于printf当然是输出在szPrintf[]内
                                StringCchPrintf(szPrintf,15,L"噢,我被重绘了%d次",iPaintAgain);
                                DrawText(hdc,szPrintf,-1,&rect,
                                        DT_SINGLELINE | DT_CENTER | DT_VCENTER);

                                hButton = FindWindowEx(hwnd,NULL,L"Button",L"random");//获取子窗口
                                DestroyWindow(hButton);                                 //销毁子窗口
                                GetClientRect(hwnd,&rect);                              //获取客户区大小
                                fxLocation = (rect.right - 60) / 2;                     //计算客户区更新后按钮的x坐标
                                fyLocation = (float)(rect.bottom - 30) / 1.6;         //计算客户区更新后按钮的y坐标
                                hButton = CreateWindow(L"Button",L"random",WS_VISIBLE | WS_CHILD,
                                        (int)fxLocation,(int)fyLocation,60,30,hwnd,NULL,NULL,NULL);
                        }



麻烦各位帮帮忙对源码有看不懂的尽管问   我想知道这个问题的根源

freeparty 发表于 2014-8-6 08:16:48

DrawText好像只能在WM_PAINT消息下使用,
别处的话要用TextOut

计机羊咩咩 发表于 2014-8-6 11:01:05

freeparty 发表于 2014-8-6 08:16
DrawText好像只能在WM_PAINT消息下使用,
别处的话要用TextOut

事实上DrawText也是用在WM_PAINT下的

戏++ 发表于 2014-8-6 12:09:09

hButton = CreateWindow(L"Button",L"random",WS_VISIBLE | WS_CHILD,
                                        (int)fxLocation,(int)fyLocation,60,30,hwnd,NULL,NULL,NULL);

这些东西最好别放在paint里面

计机羊咩咩 发表于 2014-8-6 12:40:16

戏++ 发表于 2014-8-6 12:09
hButton = CreateWindow(L"Button",L"random",WS_VISIBLE | WS_CHILD,
                              ...

嗯嗯,事实上我看了下第四章也发现自己错哪了,只是感觉自己跨越太多导致不会处理,子窗口控件是第六章的知识。

戏++ 发表于 2014-8-7 08:43:15

呵呵循序渐进吧

新浪 发表于 2014-8-7 11:03:56

简直是看不懂

计机羊咩咩 发表于 2014-8-7 11:08:19

新浪 发表于 2014-8-7 11:03
简直是看不懂

那是因为你没学windows吧,这是最基本的结构

智商负 发表于 2014-8-7 14:19:58

C语言编写的,确实我只看得懂汇编的,C语言的话还不知道如何调用WIN32API

tlwangxd 发表于 2014-11-17 10:53:25

看看

智商是硬伤 发表于 2015-8-29 08:51:18

{:7_146:}
页: [1]
查看完整版本: 论WM_PAINT消息不断发送的原因