1 #include <windows.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 #define CELL_SIZE 10 6 7 static RGBQUAD Colors[] = 8 { 9 { 0x00, 0x00, 0x00, 0x00 }, // black 10 { 0x00, 0x00, 0x80, 0x00 }, // red 11 { 0x00, 0x80, 0x00, 0x00 }, // green 12 { 0x00, 0x80, 0x80, 0x00 }, // brown 13 { 0x80, 0x00, 0x00, 0x00 }, // blue 14 { 0x80, 0x00, 0x80, 0x00 }, // magenta 15 { 0x80, 0x80, 0x00, 0x00 }, // cyan 16 { 0x80, 0x80, 0x80, 0x00 }, // dark gray 17 { 0xc0, 0xc0, 0xc0, 0x00 }, // light gray 18 { 0x00, 0x00, 0xFF, 0x00 }, // bright red 19 { 0x00, 0xFF, 0x00, 0x00 }, // bright green 20 { 0x00, 0xFF, 0xFF, 0x00 }, // bright yellow 21 { 0xFF, 0x00, 0x00, 0x00 }, // bright blue 22 { 0xFF, 0x00, 0xFF, 0x00 }, // bright magenta 23 { 0xFF, 0xFF, 0x00, 0x00 }, // bright cyan 24 { 0xFF, 0xFF, 0xFF, 0x00 } // bright white 25 }; 26 27 LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM); 28 29 int WINAPI 30 WinMain(HINSTANCE hInstance, 31 HINSTANCE hPrevInstance, 32 LPSTR lpszCmdLine, 33 int nCmdShow) 34 { 35 WNDCLASS wc; 36 MSG msg; 37 HWND hWnd; 38 39 wc.lpszClassName = "DibTestClass"; 40 wc.lpfnWndProc = MainWndProc; 41 wc.style = CS_VREDRAW | CS_HREDRAW; 42 wc.hInstance = hInstance; 43 wc.hIcon = LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION); 44 wc.hCursor = LoadCursor(NULL, (LPCTSTR)IDC_ARROW); 45 wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); 46 wc.lpszMenuName = NULL; 47 wc.cbClsExtra = 0; 48 wc.cbWndExtra = 0; 49 if (RegisterClass(&wc) == 0) 50 { 51 fprintf(stderr, "RegisterClass failed (last error 0x%lX)\n", 52 GetLastError()); 53 return(1); 54 } 55 56 hWnd = CreateWindow("DibTestClass", 57 "DIB Test", 58 WS_OVERLAPPEDWINDOW, 59 CW_USEDEFAULT, 60 CW_USEDEFAULT, 61 25 * CELL_SIZE + 5, 62 25 * CELL_SIZE + 20, 63 NULL, 64 NULL, 65 hInstance, 66 NULL); 67 if (hWnd == NULL) 68 { 69 fprintf(stderr, "CreateWindow failed (last error 0x%lX)\n", 70 GetLastError()); 71 return(1); 72 } 73 74 ShowWindow(hWnd, nCmdShow); 75 76 while(GetMessage(&msg, NULL, 0, 0)) 77 { 78 TranslateMessage(&msg); 79 DispatchMessage(&msg); 80 } 81 82 return msg.wParam; 83 } 84 85 static void PaintCells(HDC WindowDC, WORD BitCount1, WORD BitCount2, 86 int XDest, int YDest) 87 { 88 HBRUSH Brush; 89 RECT Rect; 90 UINT row, col; 91 BITMAPINFO *BitmapInfo; 92 HBITMAP DIB1, DIB2; 93 HDC DC1, DC2; 94 95 BitmapInfo = malloc(sizeof(BITMAPINFO) + 15 * sizeof(RGBQUAD)); 96 BitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 97 BitmapInfo->bmiHeader.biWidth = 4 * CELL_SIZE + 9; 98 BitmapInfo->bmiHeader.biHeight = -(4 * CELL_SIZE + 9); // it's top down (since BI_RGB is used, the sign is operative of direction) 99 BitmapInfo->bmiHeader.biPlanes = 1; 100 BitmapInfo->bmiHeader.biBitCount = BitCount1; 101 BitmapInfo->bmiHeader.biCompression = BI_RGB; 102 BitmapInfo->bmiHeader.biSizeImage = 0; 103 BitmapInfo->bmiHeader.biXPelsPerMeter = 0; 104 BitmapInfo->bmiHeader.biYPelsPerMeter = 0; 105 BitmapInfo->bmiHeader.biClrUsed = 16; 106 BitmapInfo->bmiHeader.biClrImportant = 16; 107 for (col = 0; col < 16; col++) { 108 BitmapInfo->bmiColors[col] = Colors[col]; 109 } 110 DIB1 = CreateDIBSection(NULL, BitmapInfo, DIB_RGB_COLORS, NULL, NULL, 0); 111 DC1 = CreateCompatibleDC(NULL); 112 SelectObject(DC1, DIB1); 113 114 BitmapInfo->bmiHeader.biBitCount = BitCount2; 115 DIB2 = CreateDIBSection(NULL, BitmapInfo, DIB_RGB_COLORS, NULL, NULL, 0); 116 DC2 = CreateCompatibleDC(NULL); 117 SelectObject(DC2, DIB2); 118 free(BitmapInfo); 119 120 /* Now paint on the first bitmap */ 121 for (row = 0; row < 4; row++) 122 { 123 for (col = 0; col < 4; col++) 124 { 125 Brush = CreateSolidBrush(RGB(Colors[4 * row + col].rgbRed, 126 Colors[4 * row + col].rgbGreen, 127 Colors[4 * row + col].rgbBlue)); 128 Rect.left = CELL_SIZE * col + 5; 129 Rect.top = CELL_SIZE * row + 5; 130 Rect.right = Rect.left + CELL_SIZE; 131 Rect.bottom = Rect.top + CELL_SIZE; 132 FillRect(DC1, &Rect, Brush); 133 DeleteObject(Brush); 134 } 135 } 136 137 /* Copy the first bitmap to the second */ 138 BitBlt(DC2, 4, 4, 4 * CELL_SIZE, 4 * CELL_SIZE, DC1, 5, 5, SRCCOPY); 139 140 /* Show results on screen */ 141 BitBlt(WindowDC, XDest, YDest, 4 * CELL_SIZE, 4 * CELL_SIZE, DC2, 4, 4, SRCCOPY); 142 } 143 144 LRESULT CALLBACK MainWndProc(HWND Wnd, UINT msg, WPARAM wParam, LPARAM lParam) 145 { 146 PAINTSTRUCT ps; 147 HDC WindowDC; 148 149 switch(msg) 150 { 151 case WM_PAINT: 152 WindowDC = BeginPaint(Wnd, &ps); 153 154 PaintCells(WindowDC, 4, 4, 0, 0); 155 PaintCells(WindowDC, 4, 8, 5 * CELL_SIZE, 0); 156 PaintCells(WindowDC, 4, 16, 10 * CELL_SIZE, 0); 157 PaintCells(WindowDC, 4, 24, 15 * CELL_SIZE, 0); 158 PaintCells(WindowDC, 4, 32, 20 * CELL_SIZE, 0); 159 160 PaintCells(WindowDC, 8, 4, 0, 5 * CELL_SIZE); 161 PaintCells(WindowDC, 8, 8, 5 * CELL_SIZE, 5 * CELL_SIZE); 162 PaintCells(WindowDC, 8, 16, 10 * CELL_SIZE, 5 * CELL_SIZE); 163 PaintCells(WindowDC, 8, 24, 15 * CELL_SIZE, 5 * CELL_SIZE); 164 PaintCells(WindowDC, 8, 32, 20 * CELL_SIZE, 5 * CELL_SIZE); 165 166 PaintCells(WindowDC, 16, 4, 0, 10 * CELL_SIZE); 167 PaintCells(WindowDC, 16, 8, 5 * CELL_SIZE, 10 * CELL_SIZE); 168 PaintCells(WindowDC, 16, 16, 10 * CELL_SIZE, 10 * CELL_SIZE); 169 PaintCells(WindowDC, 16, 24, 15 * CELL_SIZE, 10 * CELL_SIZE); 170 PaintCells(WindowDC, 16, 32, 20 * CELL_SIZE, 10 * CELL_SIZE); 171 172 PaintCells(WindowDC, 24, 4, 0, 15 * CELL_SIZE); 173 PaintCells(WindowDC, 24, 8, 5 * CELL_SIZE, 15 * CELL_SIZE); 174 PaintCells(WindowDC, 24, 16, 10 * CELL_SIZE, 15 * CELL_SIZE); 175 PaintCells(WindowDC, 24, 24, 15 * CELL_SIZE, 15 * CELL_SIZE); 176 PaintCells(WindowDC, 24, 32, 20 * CELL_SIZE, 15 * CELL_SIZE); 177 178 PaintCells(WindowDC, 32, 4, 0, 20 * CELL_SIZE); 179 PaintCells(WindowDC, 32, 8, 5 * CELL_SIZE, 20 * CELL_SIZE); 180 PaintCells(WindowDC, 32, 16, 10 * CELL_SIZE, 20 * CELL_SIZE); 181 PaintCells(WindowDC, 32, 24, 15 * CELL_SIZE, 20 * CELL_SIZE); 182 PaintCells(WindowDC, 32, 32, 20 * CELL_SIZE, 20 * CELL_SIZE); 183 184 EndPaint(Wnd, &ps); 185 break; 186 187 case WM_DESTROY: 188 PostQuitMessage(0); 189 break; 190 191 default: 192 return DefWindowProc(Wnd, msg, wParam, lParam); 193 } 194 195 return 0; 196 } 197