The ROP2LOOK Program

The ROP2LOOK program, shown in Figure 12-2, lets you experiment with these 16 ROP2 codes.

ROP2LOOK.MAK

#------------------------

# ROP2LOOK.MAK make file

#------------------------

rop2look.exe : rop2look.obj rop2look.def rop2look.res

link rop2look, /align:16, NUL, /nod slibcew libw, rop2look

rc rop2look.res

rop2look.obj : rop2look.c

cl -c -Gsw -Ow -W2 -Zp rop2look.c

rop2look.res : rop2look.rc

rc -r rop2look.rc

ROP2LOOK.C

/*------------------------------------------

ROP2LOOK.C -- ROP2 Demonstration Program

(c) Charles Petzold, 1990

------------------------------------------*/

#include <windows.h>

long FAR PASCAL WndProc (HWND, WORD, WORD, LONG) ;

int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,

LPSTR lpszCmdLine, int nCmdShow)

{

static char szAppName[] = "Rop2Look" ;

HWND hwnd ;

MSG msg ;

WNDCLASS wndclass ;

if (!hPrevInstance)

{

wndclass.style = CS_HREDRAW | CS_VREDRAW ;

wndclass.lpfnWndProc = WndProc ;

wndclass.cbClsExtra = 0 ;

wndclass.cbWndExtra = 0 ;

wndclass.hInstance = hInstance ;

wndclass.hIcon = NULL ;

wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground = GetStockObject (WHITE_BRUSH) ;

wndclass.lpszMenuName = szAppName ;

wndclass.lpszClassName = szAppName ;

RegisterClass (&wndclass) ;

}

hwnd = CreateWindow (szAppName, "ROP2 Demonstration Program",

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT,

NULL, NULL, hInstance, NULL) ;

ShowWindow (hwnd, nCmdShow) ;

UpdateWindow (hwnd) ;

while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;

}

long FAR PASCAL WndProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)

{

static LOGPEN lpBlack = { PS_SOLID, 1, 1, RGB ( 0, 0, 0) },

lpWhite = { PS_SOLID, 1, 1, RGB (255, 255, 255) } ;

static short nDrawingMode = R2_COPYPEN ;

HDC hdc ;

HMENU hMenu ;

HPEN hPenBlack, hPenWhite ;

PAINTSTRUCT ps ;

RECT rect ;

short i ;

switch (message)

{

case WM_COMMAND :

hMenu = GetMenu (hwnd) ;

CheckMenuItem (hMenu, nDrawingMode, MF_UNCHECKED) ;

nDrawingMode = wParam ;

CheckMenuItem (hMenu, nDrawingMode, MF_CHECKED) ;

InvalidateRect (hwnd, NULL, FALSE) ;

return 0 ;

case WM_PAINT :

hdc = BeginPaint (hwnd, &ps) ;

hPenBlack = CreatePenIndirect (&lpBlack) ;

hPenWhite = CreatePenIndirect (&lpWhite) ;

SetMapMode (hdc, MM_ANISOTROPIC) ;

GetClientRect (hwnd, &rect) ;

SetViewportExt (hdc, rect.right, rect.bottom) ;

SetWindowExt (hdc, 10, 4) ;

for (i = 0 ; i < 10 ; i += 2)

{

SetRect (&rect, i, 0, i + 2, 4) ;

FillRect (hdc, &rect, GetStockObject (i / 2)) ;

}

SetROP2 (hdc, nDrawingMode) ;

SelectObject (hdc, hPenWhite) ;

MoveTo (hdc, 1, 1) ;

LineTo (hdc, 9, 1) ;

SelectObject (hdc, hPenBlack) ;

MoveTo (hdc, 1, 3) ;

LineTo (hdc, 9, 3) ;

EndPaint (hwnd, &ps) ;

DeleteObject (hPenBlack) ;

DeleteObject (hPenWhite) ;

return 0 ;

case WM_DESTROY :

PostQuitMessage (0) ;

return 0 ;

}

return DefWindowProc (hwnd, message, wParam, lParam) ;

}

ROP2LOOK.RC

/*-----------------------------

ROP2LOOK.RC resource script

-----------------------------*/

Rop2Look MENU

{

POPUP "&Drawing Mode"

{

MENUITEM "0\tR2_BLACK", 1

MENUITEM "1\tR2_NOTMERGEPEN", 2

MENUITEM "2\tR2_MASKNOTPEN", 3

MENUITEM "3\tR2_NOTCOPYPEN", 4

MENUITEM "4\tR2_MASKPENNOT", 5

MENUITEM "5\tR2_NOT", 6

MENUITEM "6\tR2_XORPEN", 7

MENUITEM "7\tR2_NOTMASKPEN", 8

MENUITEM "8\tR2_MASKPEN", 9

MENUITEM "9\tR2_NOTXORPEN", 10

MENUITEM "A\tR2_NOP", 11

MENUITEM "B\tR2_MERGENOTPEN", 12

MENUITEM "C\tR2_COPYPEN", 13, CHECKED

MENUITEM "D\tR2_MERGEPENNOT", 14

MENUITEM "E\tR2_MERGEPEN", 15

MENUITEM "F\tR2_WHITE", 16

}

}

ROP2LOOK.DEF

;-------------------------------------

; ROP2LOOK.DEF module definition file

;-------------------------------------

NAME ROP2LOOK

DESCRIPTION 'ROP2 Demonstration Program (c) Charles Petzold, 1990'

EXETYPE WINDOWS

STUB 'WINSTUB.EXE'

CODE PRELOAD MOVEABLE DISCARDABLE

DATA PRELOAD MOVEABLE MULTIPLE

HEAPSIZE 1024

STACKSIZE 8192

EXPORTS WndProc

The program draws a background divided into five sections colored with the white, light gray, gray, dark gray, and black stock brushes (a subject that we'll get to soon). It then draws two very thick pens: a white pen on the top and a black pen on the bottom. You can select one of the 16 ROP2 codes from the menu. Figure 12-3 shows the white pen on the top and the black pen on the bottom with the drawing mode set to R2_NOTMERGEPEN: The white pen always displays as black, and the black pen inverts the destination.

ROP2LOOK uses initialized logical pen structures for the white and black pens. You'll note that both these pens have a logical width of 1. Why do they appear so thick? The program uses the MM_ANISOTROPIC mapping mode and sets the width of the client area to 10 logical units and the height to 4 logical units. The pens are therefore one-tenth the width of the client area.