• WM_PAINT、WM_ERASEBKGND、InvalidateRect、Invalidate之间的关系转


     当WM_PAINT不是由InvalidateRect产生时,即由最大化,最小化等产生时,或者移动产生(移动有时只会产生WM_ERASEBKGND消息)系统先发送WM_ERASEBKGND消息,再发送WM_PAINT消息.

        如果处理WM_ERASEBKGND消息时返回FALSE,BeginPaint标记pt.fErase 为TRUE,如果处理WM_ERASEBKGND时返回TRUE,BeginPaint标记pt.fErase为FALSE.


        当WM_PAINT由InvalidateRect产生时,先发送WM_PAINT消息(异步),如果InvalidateRect的bErase为 TRUE,BeginPaint检查到更新区域需要删除背景,向窗口发送一个WM_ERASEBKGND消息,如果处理WM_ERASEBKGND消息时 返回FALSE,BeginPaint标记pt.fErase 为TRUE,如果处理WM_ERASEBKGND时返回TRUE,BeginPaint标记pt.fErase为FALSE.

        如果pt.fErase标记为TRUE,指示应用程序应该处理背景,但是应用程序不一定需要处理,pt.fErase只是作为一个标记.

        补充:DefWindowProc(hWnd, message, wParam, lParam)处理WM_ERASEBKGND消息时默认用下面的画刷清除背景
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

    WM_ERASEBKGND返回TRUE和返回FALSE是一个规范,一般情况下没有什么区别,但是如果什么时候用到了,会根据函数返回值判断后续处理。因此最好按照要求返回数据.


    最后再提供一些测试代码,让大家更好的理解上面的内容。
    // WM_ERASEBKGNDTest.cpp : Defines the entry point for the application.
    //

    #include "stdafx.h"
    #include "WM_ERASEBKGNDTest.h"

    #define MAX_LOADSTRING 100

    // Global Variables:
    HINSTANCE hInst;        // current instance
    TCHAR szTitle[MAX_LOADSTRING];     // The title bar text
    TCHAR szWindowClass[MAX_LOADSTRING];   // the main window class name

    // Forward declarations of functions included in this code module:
    ATOM    MyRegisterClass(HINSTANCE hInstance);
    BOOL    InitInstance(HINSTANCE, int);
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);

    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
     UNREFERENCED_PARAMETER(hPrevInstance);
     UNREFERENCED_PARAMETER(lpCmdLine);

      // TODO: Place code here.
     MSG msg;
     HACCEL hAccelTable;

     // Initialize global strings
     LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
     LoadString(hInstance, IDC_WM_ERASEBKGNDTEST, szWindowClass, MAX_LOADSTRING);
     MyRegisterClass(hInstance);

     // Perform application initialization:
     if (!InitInstance (hInstance, nCmdShow))
     {
      return FALSE;
     }

     hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WM_ERASEBKGNDTEST));

     // Main message loop:
     while (GetMessage(&msg, NULL, 0, 0))
     {
      if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
      {
       TranslateMessage(&msg);
       DispatchMessage(&msg);
      }
     }

     return (int) msg.wParam;
    }

    //
    //  FUNCTION: MyRegisterClass()
    //
    //  PURPOSE: Registers the window class.
    //
    //  COMMENTS:
    //
    //    This function and its usage are only necessary if you want this code
    //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
    //    function that was added to Windows 95. It is important to call this function
    //    so that the application will get 'well formed' small icons associated
    //    with it.
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
     WNDCLASSEX wcex;

     wcex.cbSize = sizeof(WNDCLASSEX);

     wcex.style   = CS_HREDRAW | CS_VREDRAW;
     wcex.lpfnWndProc = WndProc;
     wcex.cbClsExtra  = 0;
     wcex.cbWndExtra  = 0;
     wcex.hInstance  = hInstance;
     wcex.hIcon   = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WM_ERASEBKGNDTEST));
     wcex.hCursor  = LoadCursor(NULL, IDC_ARROW);
     wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    // wcex.hbrBackground = NULL;
     wcex.lpszMenuName = MAKEINTRESOURCE(IDC_WM_ERASEBKGNDTEST);
     wcex.lpszClassName = szWindowClass;
     wcex.hIconSm  = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

     return RegisterClassEx(&wcex);
    }

    //
    //   FUNCTION: InitInstance(HINSTANCE, int)
    //
    //   PURPOSE: Saves instance handle and creates main window
    //
    //   COMMENTS:
    //
    //        In this function, we save the instance handle in a global variable and
    //        create and display the main program window.
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       HWND hWnd;

       hInst = hInstance; // Store instance handle in our global variable

       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

       if (!hWnd)
       {
          return FALSE;
       }

       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);

       return TRUE;
    }

    //
    //  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  PURPOSE:  Processes messages for the main window.
    //
    //  WM_COMMAND - process the application menu
    //  WM_PAINT - Paint the main window
    //  WM_DESTROY - post a quit message and return
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
     int wmId, wmEvent;
     PAINTSTRUCT ps;
     HDC hdc;

     switch (message)
     {
     case WM_COMMAND:
      wmId    = LOWORD(wParam);
      wmEvent = HIWORD(wParam);
      // Parse the menu selections:
      switch (wmId)
      {
      case IDM_ABOUT:
       DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
       break;
      case IDM_EXIT:
       DestroyWindow(hWnd);
       break;
      default:
       return DefWindowProc(hWnd, message, wParam, lParam);
      }
      break;
     case WM_LBUTTONDOWN:
      RECT rect;
      GetClientRect(hWnd, &rect);
      InvalidateRect(hWnd, &rect, TRUE);
      MessageBeep(2);
      break;

     //case WM_ERASEBKGND:
     // OutputDebugString(_T("Enter WM_ERASEBKGND/n"));
     // return 1;
     // break;
      
     case WM_PAINT:
      OutputDebugString(_T("Enter WM_PAINT/n"));
      hdc = BeginPaint(hWnd, &ps);

      if (ps.fErase == TRUE)
       OutputDebugString(_T("ps.fErase == TRUE/n/n"));
      // TODO: Add any drawing code here...
      EndPaint(hWnd, &ps);
      break;
     case WM_DESTROY:
      PostQuitMessage(0);
      break;
     default:
      if (WM_ERASEBKGND == message)
       OutputDebugString(_T("Enter WM_ERASEBKGND/n"));
      return DefWindowProc(hWnd, message, wParam, lParam);
     }

    // DefWindowProc(hWnd, message, wParam, lParam);
     return 0;
    }

    // Message handler for about box.
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
     UNREFERENCED_PARAMETER(lParam);
     switch (message)
     {
     case WM_INITDIALOG:
      return (INT_PTR)TRUE;

     case WM_COMMAND:
      if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
      {
       EndDialog(hDlg, LOWORD(wParam));
       return (INT_PTR)TRUE;
      }
      break;
     }
     return (INT_PTR)FALSE;
    }

  • 相关阅读:
    统计:概述
    概率论总结
    概率论13 中心极限定律
    概率论12 矩与矩生成函数
    概率论11 协方差与相关系数
    概率论10 方差与标准差
    概率论09 期望
    概率论08 随机变量的函数
    mysql 分区
    Linux 搭建svn版本库
  • 原文地址:https://www.cnblogs.com/fwycmengsoft/p/3026395.html
Copyright © 2020-2023  润新知