LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    RECT wndREC;    switch (message) 
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam); 
        wmEvent = HIWORD(wParam); 
        // 分析菜单选择:
        switch (wmId)
        {
        case IDM_ABOUT:
            //::SendMessage(hWnd,9999,0,0);
            DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    //case WM_PAINT:
        //hdc = BeginPaint(hWnd, &ps);
//        EndPaint(hWnd, &ps);
        //break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_CHAR:
        ::CreateWindow("myWnd","aa",WS_CHILD|WS_VISIBLE|WS_CAPTION|WS_THICKFRA
ME,100,100,300,300,hWnd,NULL,hInst,NULL);
        break;
    case 9999:
        hdc = GetDC(hWnd);
        TextOut(hdc,100,100,"helllow",7);
        DeleteDC(hdc);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}假如我产生两个子窗口在主窗口下,然后两个字窗口重叠,再把下面的子窗口移出来,就
会发现该窗口背景没有擦除,似乎上面还有一个窗口似的,
假如发送WM_ERASEBACKGROUND消息,又只有客户区擦除,其余地方还是那样。

解决方案 »

  1.   


    // 32.cpp : 定义应用程序的入口点。
    //#include "stdafx.h"
    #include "32.h"
    #define MAX_LOADSTRING 100// 全局变量:
    HINSTANCE hInst; // 当前实例
    TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
    TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名// 此代码模块中包含的函数的前向声明:
    ATOM MyRegisterClass(HINSTANCE hInstance);
    BOOL InitInstance(HINSTANCE, int);
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK WndProc2(HWND, UINT, WPARAM, LPARAM);
    LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
      // TODO: 在此放置代码。
    MSG msg;
    HACCEL hAccelTable; // 初始化全局字符串
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_MY, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance); // 执行应用程序初始化:
    if (!InitInstance (hInstance, nCmdShow)) 
    {
    return FALSE;
    } hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MY); // 主消息循环:
    while (GetMessage(&msg, NULL, 0, 0)) 
    {
    if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    } return (int) msg.wParam;
    }//
    //  函数: MyRegisterClass()
    //
    //  目的: 注册窗口类。
    //
    //  注释: 
    //
    //    仅当希望在已添加到 Windows 95 的
    //    “RegisterClassEx”函数之前此代码与 Win32 系统兼容时,
    //    才需要此函数及其用法。调用此函数
    //    十分重要,这样应用程序就可以获得关联的
    //   “格式正确的”小图标。
    //
    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 = LoadIcon(hInstance, (LPCTSTR)IDI_MY);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
    wcex.lpszMenuName = (LPCTSTR)IDC_MY;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); RegisterClassEx(&wcex);
    wcex.hbrBackground = (HBRUSH)::GetStockObject(GRAY_BRUSH);
    wcex.lpszClassName = "myWnd";
    wcex.lpfnWndProc = (WNDPROC)WndProc2;
    return RegisterClassEx(&wcex);
    }//
    //   函数: InitInstance(HANDLE, int)
    //
    //   目的: 保存实例句柄并创建主窗口
    //
    //   注释: 
    //
    //        在此函数中,我们在全局变量中保存实例句柄并
    //        创建和显示主程序窗口。
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       HWND hWnd;   hInst = hInstance; // 将实例句柄存储在全局变量中   hWnd = CreateWindowEx(WS_EX_CLIENTEDGE,szWindowClass, szTitle, WS_OVERLAPPEDWINDOW|WS_VSCROLL|WS_HSCROLL,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);   if (!hWnd)
       {
          return FALSE;
       }   ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);   return TRUE;
    }//
    //  函数: WndProc(HWND, unsigned, WORD, LONG)
    //
    //  目的: 处理主窗口的消息。
    //
    //  WM_COMMAND - 处理应用程序菜单
    //  WM_PAINT - 绘制主窗口
    //  WM_DESTROY - 发送退出消息并返回
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    RECT wndREC; switch (message) 
    {
    case WM_COMMAND:
    wmId    = LOWORD(wParam); 
    wmEvent = HIWORD(wParam); 
    // 分析菜单选择:
    switch (wmId)
    {
    case IDM_ABOUT:
    //::SendMessage(hWnd,9999,0,0);
    DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
    break;
    case IDM_EXIT:
    DestroyWindow(hWnd);
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    break;
    //case WM_PAINT:
    //hdc = BeginPaint(hWnd, &ps);
    // EndPaint(hWnd, &ps);
    //break;
    case WM_DESTROY:
    PostQuitMessage(0);
    break;
    case WM_CHAR:
    ::CreateWindow("myWnd","aa",WS_CHILD|WS_VISIBLE|WS_CAPTION|WS_THICKFRAME,100,100,300,300,hWnd,NULL,hInst,NULL);
    break;
    case 9999:
    hdc = GetDC(hWnd);
    TextOut(hdc,100,100,"helllow",7);
    DeleteDC(hdc);
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
    }
    LRESULT CALLBACK WndProc2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    static int i;
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    RECT wndREC;
    char szStr[16]; switch (message) 
    {
    case WM_COMMAND:
    wmId    = LOWORD(wParam); 
    wmEvent = HIWORD(wParam); 
    // 分析菜单选择:
    switch (wmId)
    {
    case IDM_ABOUT:
    //::SendMessage(hWnd,9999,0,0);
    DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
    break;
    case IDM_EXIT:
    DestroyWindow(hWnd);
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    break;
    case WM_PAINT:
    // GetWindowRect(hWnd,&wndREC);
    // InvalidateRect(hWnd,&wndREC,TRUE);
    i++;
    memset(szStr,0,16);
    itoa(i,szStr,10);
    ::SetWindowText(hWnd,szStr);
    hdc = BeginPaint(hWnd, &ps);
    // TextOut(hdc,100,100,"helllow",7);

    EndPaint(hWnd, &ps);
    // UpdateWindow(hWnd);
    break;
    case WM_MOVE:
    // MessageBox(hWnd,"ss","ss",MB_OK);
    hdc = GetDC(hWnd);
    SendMessage(hWnd,WM_ERASEBKGND,(DWORD)hdc,0);
    ReleaseDC(hWnd,hdc);
    break;
    case WM_DESTROY:
    PostQuitMessage(0);
    break;
    case 9999:
    hdc = GetDC(hWnd);
    TextOut(hdc,100,100,"helllow",7);
    DeleteDC(hdc);
    break;
    default:
    return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
    }// “关于”框的消息处理程序。
    LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    HWND hWnd;
    HDC hdc;
    switch (message)
    {
    case WM_INITDIALOG:
    return TRUE; case WM_COMMAND:
    if (LOWORD(wParam) == IDCANCEL) 
    {
    EndDialog(hDlg, LOWORD(wParam));
    return TRUE;
    }
    if(LOWORD(wParam) == IDOK  )
    {
    hWnd = GetParent(hDlg);
    hdc = GetDC(hWnd);
    TextOut(hdc,0,0,"ggggggg",7);
    ReleaseDC(hWnd,hdc);
    ::SendMessage(hWnd,9999,0,0);
    return TRUE;
    }
    break;
    }
    return FALSE;
    }
      

  2.   

    只有客户区被擦除?你再试试WM_NCPAINT。
      

  3.   

    你应该重新注册一个子窗口类
    ATOM MyRegisterClass(HINSTANCE hInstance);
    ATOM MyRegisterClass1(HINSTANCE hInstance);int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
      MSG msg;
    HACCEL hAccelTable; MyRegisterClass(hInstance);
    MyRegisterClass1(hInstance);         ... return (int) msg.wParam;
    }ATOM MyRegisterClass1(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 = 0;
    wcex.hCursor = 0;
    wcex.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH);
    wcex.lpszMenuName = 0;
    wcex.lpszClassName = "MY_CHILD";
    wcex.hIconSm = 0; RegisterClassEx(&wcex);
    wcex.hbrBackground = (HBRUSH)::GetStockObject(GRAY_BRUSH);
    wcex.lpszClassName = "myChild";
    wcex.lpfnWndProc = (WNDPROC)WndProc2;
    return RegisterClassEx(&wcex);
    }
      

  4.   

    case WM_CHAR:
    ::CreateWindow("myChild","aa",WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_THICKFRAME,100,100,300,300,hWnd,NULL,hInst,NULL);
    break;
      

  5.   

    我主要不明白windows默认处理什么时候擦除窗口,在程序里我在子窗口WM_PAINT消息里加了一个计数器,然后移动窗口时,有的时候重画,有的时候不重画,即便重画,也不擦除任何东西,假如我在WM_MOVE里面加入WM_ERASEBACKGROUND,只是客户区被擦除。而且有的时候,两个子窗口一块重画,假如移动的窗口没有彻底移动出来,另一个窗口的标题栏说不定反而把移动的窗口覆盖了,似乎发生移动的窗口仍在下面似的。
    假如最小化然后复原,一切的乱画全消失了,我就想明白最小化而后复原时,windows究竟发送了那些消息。
      

  6.   

    case 9999:
            hdc = GetDC(hWnd);
            TextOut(hdc,100,100,"helllow",7);
            DeleteDC(hdc);//改为ReleaseDC(hWnd, hdc);