The arrow on the line indicates the direction in which the line is drawn. Both the WINDING mode and the ALTERNATE mode fill in three closed L-shaped areas, numbered from 1 to 3. The two smaller inner regions, numbered 4 and 5, are not filled in ALTERNATE mode. But in WINDING mode, the area number 5 will be filled, because the inside of the area to reach the outside of the figure must cross two lines in the same direction. The area with number 4 will not be filled because the ray must pass through two border lines, but the two border lines are drawn in opposite directions.
1 /*------------------------------------------- 2 ALTWIND.C -- Alternate and Winding Fill Modes 3 (c) Charles Petzold, 1998 4 -------------------------------------------*/ 5 6 #include <Windows.h> 7 8 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 9 10 int WINAPI WinMain( __in HINSTANCE hInstance 11 , __in_opt HINSTANCE hPrevInstance 12 , __in LPSTR lpCmdLine 13 , __in int nShowCmd ) 14 { 15 static TCHAR szAppName[] = TEXT("AltWind"); 16 HWND hwnd; 17 MSG msg; 18 WNDCLASS wndclass; 19 20 wndclass.style = CS_HREDRAW | CS_VREDRAW; 21 wndclass.lpfnWndProc = WndProc; 22 wndclass.cbClsExtra = 0; 23 wndclass.cbWndExtra = 0; 24 wndclass.hInstance = hInstance; 25 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 26 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); 27 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 28 wndclass.lpszMenuName = NULL; 29 wndclass.lpszClassName = szAppName; 30 31 if (!RegisterClass(&wndclass)) 32 { 33 MessageBox(NULL, TEXT("Program requires Windows NT!") 34 , szAppName, MB_ICONERROR); 35 return 0; 36 } 37 38 hwnd= CreateWindow(szAppName, TEXT("Alternate and Winding Fill Modes") 39 , WS_OVERLAPPEDWINDOW 40 , CW_USEDEFAULT, CW_USEDEFAULT 41 , CW_USEDEFAULT, CW_USEDEFAULT 42 , NULL, NULL, hInstance, NULL); 43 44 ShowWindow(hwnd, nShowCmd); 45 UpdateWindow(hwnd); 46 47 while (GetMessage(&msg, NULL, 0, 0)) 48 { 49 TranslateMessage(&msg); 50 DispatchMessage(&msg); 51 } 52 53 return msg.wParam; 54 } 55 56 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 57 { 58 static POINT aptFigure[10] = {10, 70 59 , 50, 70 60 , 50, 10 61 , 90, 10 62 , 90, 50 63 , 30, 50 64 , 30, 90 65 , 70, 90 66 , 70, 30 67 , 10, 30}; 68 static int cxClient, cyClient; 69 HDC hdc; 70 int i; 71 PAINTSTRUCT ps; 72 POINT apt[10]; 73 74 switch (message) 75 { 76 case WM_SIZE: 77 cxClient = LOWORD(lParam); 78 cyClient = HIWORD(lParam); 79 return 0; 80 81 case WM_PAINT: 82 hdc = BeginPaint(hwnd, &ps); 83 SelectObject(hdc, GetStockObject(GRAY_BRUSH)); 84 85 for (i = 0; i !=10; ++i) 86 { 87 apt[i].x = cxClient * aptFigure[i].x / 200; 88 apt[i].y = cyClient * aptFigure[i].y / 100; 89 } 90 SetPolyFillMode(hdc, ALTERNATE); 91 Polygon(hdc, apt, 10); 92 93 for (i = 0; i != 10; ++i) 94 { 95 apt[i].x += cxClient / 2; 96 } 97 SetPolyFillMode(hdc, WINDING); 98 Polygon(hdc, apt, 10); 99 100 EndPaint(hwnd, &ps); 101 return 0; 102 103 case WM_DESTROY: 104 PostQuitMessage(0); 105 return 0; 106 } 107 108 return DefWindowProc(hwnd, message, wParam, lParam); 109 }
The coordinates of the figure (set in a 100*100 unit area) are stored in the aptFigure array. These coordinates are scaled proportionally to the width and height of the client. The program displays two graphs, one using the ALTERNATE fill mode and the other using the WINDING fill mode. The result is as follows: