[視窗重繪技術--虛擬視窗實現法]

來源:互聯網
上載者:User

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

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

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

HINSTANCE pInstance;

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:{

      [COLOR=green] 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);
 [COLOR=green]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中去 */[/COLOR]  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;

 }
 return 0;
 break;

case WM_DESTROY:
 DeleteDC(memDC);//釋放記憶體裝置描述表
 DeleteObject(hBitmap); PostQuitMessage(0);
 return 0;
}
return DefWindowProc(hwnd,iMsg,wParam,lParam);
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.