日期:2014-05-17  浏览次数:20928 次

windows程序设计 绘图模式--SetROP2

设备内容中定义的绘图方式也影响显示器上所画线的外观。设想画这样一条直线,它的色彩由画笔色彩和画线区域原来的色彩共同决定。设想用同一种画笔在白色表面上画出黑线而在黑色表面上画出白线,而且不用知道表面是什么色彩。这样的功能对您有用吗?通过绘图方式的设定,这些都可以实作。

      当Windows使用画笔来画线时,它实际上执行画笔图素与目标位置处原来图素之间的某种位布尔运算。图素间的位布尔运算叫做「位映像运算」,简称为「ROP」。由于画一条直线只涉及两种图素(画笔和目标),因此这种布尔运算又称为「二元位映像运算」,简记为「ROP2」。Windows定义了16种ROP2代码,表示Windows组合画笔图素和目标图素的方式。在内定设备内容中,绘图方式定义为R2_COPYPEN,这意味着Windows只是将画笔图素复制到目标图素,这也是我们通常所熟知的。此外,还有15种ROP2码。在此处就不列出其余的15中ROP2码了,在《Windows程序设计》一书中有详解。

      现在通过程序进行详解解释:

View Code 
 #include <windows.h>
 
 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, PSTR szCmdLine, int iCmdShow)
 {
     static TCHAR szAppName[] = TEXT("FillRect");
     HWND hwnd;
     MSG msg;
     WNDCLASS 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.lpszClassName = szAppName;
     wndclass.lpszMenuName = NULL;
 
     if (!RegisterClass(&wndclass))
     {
         MessageBox(NULL, TEXT("This program requires Windows NT!"),    szAppName, MB_ICONERROR);
         return 0;
     }
 
     hwnd = CreateWindow(szAppName, 
         TEXT("FillRect"), 
         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;
     HBRUSH hBrush;
     RECT rectBrush;
     HPEN hPen;
 
     static int cxClient, cyClient;
     switch(iMsg)
     {
     case WM_SIZE:
         cxClient = LOWORD(lParam);
         cyClient = HIWORD(lParam);
         return 0;
     case WM_PAINT:
         hdc = BeginPaint(hwnd, &ps);
 
         SetROP2(hdc, R2_MASKPEN);
 
         // Rectangle
         hPen = CreatePen(PS_SOLID, 2, RGB(0, 255, 0));
         SelectObject(hdc, hPen);
         Rectangle(hdc, cxClient / 2 - 50, cyClient / 2 - 50, cxClient / 2 + 50, cyClient / 2 + 50);
 
         // Ellipse
         Ellipse(hdc, cxClient / 2 - 100, cyClient / 2 - 50, cxClient / 2 + 100, cyClient / 2 + 50);
 
         // FillRect
         hBrush = CreateSolidBrush(RGB(255, 0, 0));
         SetRect(&rectBrush, cxClient / 2 - 25, cyClient / 2 - 25, cxClient / 2 + 25, cyClient / 2 + 25);
         FillRect(hdc, &rectBrush, hBrush);
         EndPaint(hwnd, &ps);
         DeleteObject(hPen);
         return 0;
     case WM_DESTROY:
         PostQuitMessage(0);
         return 0;
     }
     return DefWindowProc(hwnd, iMsg, wParam, lParam);
 }

在代码中,有SetROP2(hdc, R2_MASKPEN);这样一句,当去掉这句话时运行程序,结果如下: