文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>窗口重绘技术--虚拟窗口实现法(转载)

窗口重绘技术--虚拟窗口实现法(转载)

时间:2010-10-25  来源:Hailoong

1 Windows程序是图形窗口,各窗口之间可以互相切换。然而,就在这窗口的切换之中,涉及到一个窗口重绘的问题:当A窗口被B窗口覆盖或者部分覆盖之后,移去B窗口时,A窗口中的内容会被B窗口擦去……

2---------------------------
当B窗口移去的时候,如何实现A窗口的重绘呢?
这里有三种方法:
1)当窗口的内容是用某种计算方法创建的时候,可以的WM_PAINT消息处理之中再次计算重新绘出窗口。这种方法适用于计算量很小的情况,否则,计算时间太长,重绘效果仍然不理想~

2)预先保存窗口显示事件的记录,当窗口重绘的时候,再使这些事件发生。

3) 建立一个与显示窗口(屏幕上的应用程序窗口)对应的虚拟窗口(相当于它的镜子),每次向显示窗口中写内容时,同时也向虚拟窗口中写入同样的内容,两者始终保持同步。
当B窗口移去时,会产生WM_PAINT消息,要求程序重绘窗口。这时,就可以直接将虚拟窗口中的内容复制到显示窗口中去,从而实现窗口的重绘!!这也是大多数Windows应用程序重绘窗口最常用的技术。

3--------------------------
实现

使用Windows API来实现该技术。分为以下3个过程:
1)创建虚拟窗口。(在WM_CREATE实现)
2)向虚拟窗口同步输出(在绘图的过程中实现)
3)重绘时,虚拟窗口拷贝到显示窗口(在WM_PAINT)中实现

附实现的源代码(如果将绿色的部分(有[color]标记的部分)注释掉,就会出现首贴中的那种不重绘的情况,因为DefWindowProc过程不会处理窗口重绘的,这写都需要程序员的劳动,所以程序员也不是吃干饭的,必须考虑周到,用最好的方法实现最好的功能-----------大家不妨试一试!)

 

#include <windows.h>
#include "resource.h"

//Globals
HINSTANCE pInstance;

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

//*******************************************************************
//   WinMain
//*******************************************************************

int WINAPI WinMain (HINSTANCE hInstance,HINSTANCE hPrevInstance,
                    PSTR szCmdLine,int iCmdShow)
{
    static char szAppName[]="AppName";
    HWND hwnd;
    MSG  msg;

    WNDCLASSEX wndclass;
    wndclass.cbSize =sizeof(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=MAKEINTRESOURCE(IDR_MENU1);
    wndclass.lpszClassName =szAppName;
    wndclass.hIconSm=LoadIcon(NULL,IDI_APPLICATION);

    RegisterClassEx(&wndclass);

    hwnd=CreateWindow(szAppName,
                      "窗口标题",
                      WS_OVERLAPPEDWINDOW,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      CW_USEDEFAULT,
                      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 iMsg,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;

    static HDC memDC;
    static HBITMAP hBitmap;
    HBRUSH hBrush;
    static int maxX,maxY;
    int response;

    switch (iMsg)
    {

    case WM_CREATE:
        maxX=GetSystemMetrics(SM_CXSCREEN);
        maxY=GetSystemMetrics(SM_CYSCREEN);
        hdc = GetDC (hwnd);   //得到当前的设备描述表
        memDC=CreateCompatibleDC(hdc);//得到兼容的设备描述表
        hBitmap=CreateCompatibleBitmap(hdc,maxX,maxY);//创建兼容位图
        SelectObject(memDC,hBitmap);//将位图选入内存设备描述表
        hBrush=(HBRUSH)GetStockObject(WHITE_BRUSH);//得到白色画刷
        SelectObject(memDC,hBrush);//将画刷选入内存设备描述表
        PatBlt(memDC,0,0,maxX,maxY,PATCOPY);//用当前画刷填充
        ReleaseDC(hwnd,hdc);//释放当前设备描述表[/COLOR]

        break;

    case WM_PAINT:
        hdc=BeginPaint(hwnd,&ps);
        BitBlt(hdc,ps.rcPaint.left,ps.rcPaint.top,ps.rcPaint.right-ps.rcPaint.left,ps.rcPaint.bottom-ps.rcPaint.top,
                            memDC,ps.rcPaint.left,ps.rcPaint.top,SRCCOPY);//对需要重画的区域进行重画
        //将memDC总得内容复制到hdc中去 */
        EndPaint(hwnd,&ps);
        return 0;
    case WM_COMMAND:
        switch (LOWORD (wParam))
        {
        case IDM_DRAW:
            hdc=GetDC(hwnd);
            int x,y,width,height;
            int red,green,blue;
            width=GetSystemMetrics(SM_CXFULLSCREEN);
            height=GetSystemMetrics(SM_CYFULLSCREEN);//得到客户区的高和宽
            for (x=0;x<width;x++)
            {  //画出晚霞~
                for (y=0;y<height;y++)
                {
                    red=x*255/width;
                    green=y*255/height;
                    blue=(x*255/width+(height-y)*255/height)/2;
                    SetPixel(hdc,x,y,RGB(red,green,blue));//输出到物理窗口
                    [COLOR=green]SetPixel(memDC,x,y,RGB(red,green,blue));//输出到虚拟窗口[/COLOR]    }
                    ReleaseDC(hwnd,hdc);
                    break;

                case IDM_CLEAR:
                    hdc=GetDC(hwnd);
                    PatBlt(hdc,0,0,maxX,maxY,PATCOPY);//清除物理屏幕
                    PatBlt(memDC,0,0,maxX,maxY,PATCOPY);//清除虚拟屏幕
                    ReleaseDC(hwnd,hdc);
                    break;


                case ID_EXIT:
                    response=MessageBox(hwnd,"真的要退出吗?","退出",MB_YESNO);
                    if (response==IDYES) PostQuitMessage(0);
                    break;

                }
            }
            break;

        case WM_DESTROY:
            DeleteDC(memDC);//释放内存设备描述表
            DeleteObject(hBitmap);
            PostQuitMessage(0);
            break;
        }
        return DefWindowProc(hwnd,iMsg,wParam,lParam);
    }

    return 0
}

相关阅读 更多 +
排行榜 更多 +
雷电觉醒安卓版

雷电觉醒安卓版

飞行射击 下载
3D幻影飞车最新版

3D幻影飞车最新版

飞行射击 下载
星河一号战队

星河一号战队

飞行射击 下载