|
|
1.1 ! root 1: /*************************************************************************** ! 2: * * ! 3: * PROGRAM : MyPal.c * ! 4: * * ! 5: * PURPOSE : Sets up a bar representation of the current physical * ! 6: * palette and displays useful information regarding * ! 7: * pixel colors and palette indices. * ! 8: * * ! 9: * FUNCTIONS : WinMain() - calls initialization function, * ! 10: * processes message loop * ! 11: * * ! 12: * WndProc() - Window function for app. Processes * ! 13: * window messages. * ! 14: * * ! 15: * ShowColor() - Displays a little box on each side of the * ! 16: * caption bar displaying the pixel color at the* ! 17: * mouse position. * ! 18: ***************************************************************************/ ! 19: ! 20: #include <windows.h> ! 21: #include "mypal.h" ! 22: ! 23: HANDLE hPal; /* Handle to the application's logical palette */ ! 24: static INT nSizeX; /* Width of the application window */ ! 25: static INT nSizeY; /* Height of the application window */ ! 26: NPLOGPALETTE pLogPal; /* Pointer to program's logical palette */ ! 27: INT nXBorder; /* Width of window border */ ! 28: INT nXTitle; /* Width of title bar */ ! 29: INT nYTitle; /* Height of title bar */ ! 30: BOOL bCaptureOn; /* Indicates if mouse capture is on */ ! 31: INT iIndex; /* Last index selected in palette */ ! 32: CHAR szTitlebuf[90];/* Buffer for pixel and palette info. text */ ! 33: HDC hDCGlobal; /* The Screen DC */ ! 34: INT iNumColors; /* Number of colors supported by device */ ! 35: INT iRasterCaps; /* Raster capabilities */ ! 36: RECT rClientRect; /* Client rectangle coordinates */ ! 37: DWORD dwPal[PALETTESIZE]; /* Stores palette entries for later lookup */ ! 38: INT iGlobalXOffset; ! 39: INT iGlobalYOffset; ! 40: INT iYMiddle; ! 41: ! 42: LONG APIENTRY WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam); ! 43: ! 44: /**************************************************************************** ! 45: * * ! 46: * FUNCTION : void ShowColor(HWND hWnd, HDC hDC) * ! 47: * * ! 48: * PURPOSE : Displays a little box on each side of the caption bar * ! 49: * displaying the pixel color at the mouse position. * ! 50: * * ! 51: ****************************************************************************/ ! 52: VOID ShowColor ( ! 53: HWND hWnd, ! 54: HDC hDC) ! 55: { ! 56: HBRUSH hBrush, hOldBrush; ! 57: ! 58: hBrush = CreateSolidBrush ( PALETTEINDEX(iIndex) ); ! 59: hOldBrush = SelectObject (hDC,hBrush) ; ! 60: ! 61: GetWindowRect (hWnd, (LPRECT)&rClientRect); ! 62: ! 63: PatBlt ( hDC, ! 64: rClientRect.left + nXTitle + nXBorder + 1, ! 65: rClientRect.top + nXBorder, ! 66: nXTitle, ! 67: nYTitle, ! 68: PATCOPY); ! 69: ! 70: PatBlt(hDC, ! 71: rClientRect.right - ( 3 * nXTitle + nXBorder + 2), ! 72: rClientRect.top + nXBorder, ! 73: nXTitle, ! 74: nYTitle, ! 75: PATCOPY); ! 76: SelectObject (hDC, hOldBrush); ! 77: DeleteObject (hBrush) ; ! 78: } ! 79: ! 80: /**************************************************************************** ! 81: * * ! 82: * FUNCTION : WinMain(HANDLE, HANDLE, LPSTR, int) * ! 83: * * ! 84: * PURPOSE : Creates the app. window and processes the message loop. * ! 85: * * ! 86: ****************************************************************************/ ! 87: int APIENTRY WinMain( ! 88: HANDLE hInstance, ! 89: HANDLE hPrevInstance, ! 90: LPSTR lpCmdLine, ! 91: int nCmdShow ! 92: ) ! 93: { ! 94: static CHAR szAppName [] = "MyPal"; ! 95: HWND hWnd; ! 96: WNDCLASS wndclass; ! 97: MSG msg ; ! 98: INT xScreen; ! 99: INT yScreen; ! 100: ! 101: UNREFERENCED_PARAMETER( lpCmdLine ); ! 102: ! 103: if (!hPrevInstance){ ! 104: wndclass.style = CS_HREDRAW | CS_VREDRAW; ! 105: wndclass.lpfnWndProc = (WNDPROC) WndProc; ! 106: wndclass.cbClsExtra = 0; ! 107: wndclass.cbWndExtra = 0; ! 108: wndclass.hInstance = hInstance; ! 109: wndclass.hIcon = LoadIcon(hInstance, szAppName); ! 110: wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); ! 111: wndclass.hbrBackground = GetStockObject (BLACK_BRUSH); ! 112: wndclass.lpszMenuName = szAppName; ! 113: wndclass.lpszClassName = szAppName; ! 114: ! 115: if (!RegisterClass (&wndclass)) ! 116: return FALSE ; ! 117: } ! 118: ! 119: /* Do some global initializations */ ! 120: xScreen = GetSystemMetrics (SM_CXSCREEN); ! 121: yScreen = GetSystemMetrics (SM_CYSCREEN); ! 122: nXBorder = (INT)GetSystemMetrics (SM_CXFRAME); ! 123: nXTitle = (INT)GetSystemMetrics (SM_CXSIZE); ! 124: nYTitle = (INT)GetSystemMetrics (SM_CYSIZE); ! 125: iIndex = 0; ! 126: bCaptureOn = FALSE; ! 127: ! 128: hDCGlobal = GetDC (NULL); ! 129: iRasterCaps = GetDeviceCaps(hDCGlobal, RASTERCAPS); ! 130: iRasterCaps = (iRasterCaps & RC_PALETTE) ? TRUE : FALSE; ! 131: ! 132: if (iRasterCaps) ! 133: iNumColors = GetDeviceCaps(hDCGlobal, SIZEPALETTE); ! 134: else ! 135: iNumColors = GetDeviceCaps( hDCGlobal, NUMCOLORS); ! 136: ReleaseDC (NULL,hDCGlobal); ! 137: ! 138: nSizeX = ((xScreen - 2*nXBorder) / PALETTESIZE) * PALETTESIZE; ! 139: ! 140: /* create the app. window */ ! 141: hWnd = CreateWindow (szAppName, ! 142: "My Physical Palette ", ! 143: WS_OVERLAPPEDWINDOW, ! 144: (xScreen-nSizeX) / 2 - nXBorder, ! 145: yScreen - ( 4 * GetSystemMetrics (SM_CYCAPTION)), ! 146: nSizeX + 2 * nXBorder, ! 147: 4 * GetSystemMetrics (SM_CYCAPTION), ! 148: NULL, ! 149: NULL, ! 150: hInstance, ! 151: NULL); ! 152: ShowWindow (hWnd, nCmdShow); ! 153: UpdateWindow (hWnd); ! 154: ! 155: while (GetMessage (&msg, NULL, 0, 0)){ ! 156: TranslateMessage (&msg) ; ! 157: DispatchMessage (&msg) ; ! 158: } ! 159: ! 160: return msg.wParam ; ! 161: } ! 162: ! 163: /****************************************************************************** ! 164: * * ! 165: * FUNCTION: WndProc(HWND, unsigned, WORD, LONG) * ! 166: * * ! 167: * PURPOSE: Processes window messages and sets up a 256 bar representation * ! 168: * of the current physical palette. Specifically, in response to: * ! 169: * * ! 170: * WM_CREATE -Allocates for and sets up a LOGPALETTE * ! 171: * structure, creates a logical palette the same * ! 172: * size as the physical palette and obtains a * ! 173: * handle to the logical palette. * ! 174: * * ! 175: * WM_DESTROY -Destroys the logical palette and shuts down app. * ! 176: * * ! 177: * WM_PAINT -Resizes client area to hold as many vertical * ! 178: * color bars as there are physical palette entries.* ! 179: * Also realises the current logical palette and * ! 180: * draws one color bar corresponding to each * ! 181: * palette entry * ! 182: * * ! 183: * WM_RBUTTONDOWN -Captures the mouse and initiates the below * ! 184: * process: * ! 185: * * ! 186: * WM_MOUSEMOVE -Following a WM_RBUTTONDOWN, if the right mouse * ! 187: * key is depressed, displays info about the * ! 188: * pixel RGB value and palette index of the mouse * ! 189: * coordinates. * ! 190: * * ! 191: * WM_RBUTTONUP -Release mouse capture and terminates the above * ! 192: * process * ! 193: * * ! 194: * WM_LBUTTONDOWN -Determines and displays the palette index and * ! 195: * RGB value of the bar under the mouse. * ! 196: * * ! 197: * WM_KEYDOWN -Allows use of the arrow keys in stepping thro' * ! 198: * palette entries. * ! 199: * * ! 200: *****************************************************************************/ ! 201: LONG APIENTRY WndProc ( ! 202: HWND hWnd, ! 203: UINT iMessage, ! 204: UINT wParam, ! 205: LONG lParam) ! 206: { ! 207: HDC hDC; ! 208: PAINTSTRUCT ps; ! 209: INT iLoop; ! 210: INT nStart; ! 211: HBRUSH hBrush; ! 212: HBRUSH hOldBrush; ! 213: ! 214: MPOINT pt; ! 215: static INT nIncr; ! 216: static DWORD dwColor; ! 217: static DWORD dwLastColor; ! 218: static INT i, x; ! 219: ! 220: switch (iMessage) { ! 221: case WM_DESTROY: ! 222: /* delete the handle to the logical palette if it has any ! 223: * color entries and quit. ! 224: */ ! 225: if (pLogPal->palNumEntries) ! 226: DeleteObject (hPal); ! 227: PostQuitMessage (0) ; ! 228: break ; ! 229: ! 230: case WM_CREATE: ! 231: /* Allocate enough memory for a logical palette with ! 232: * PALETTESIZE entries and set the size and version fields ! 233: * of the logical palette structure. ! 234: */ ! 235: pLogPal = (NPLOGPALETTE) LocalAlloc (LMEM_FIXED, ! 236: (sizeof (LOGPALETTE) + ! 237: (sizeof (PALETTEENTRY) * (PALETTESIZE)))); ! 238: ! 239: if(!pLogPal){ ! 240: MessageBox(hWnd, "<WM_CREATE> Not enough memory for palette.", NULL, MB_OK | MB_ICONHAND); ! 241: PostQuitMessage (0) ; ! 242: break; ! 243: } ! 244: ! 245: pLogPal->palVersion = 0x300; ! 246: pLogPal->palNumEntries = PALETTESIZE; ! 247: ! 248: /* fill in intensities for all palette entry colors */ ! 249: for (iLoop = 0; iLoop < PALETTESIZE; iLoop++) { ! 250: *((WORD *) (&pLogPal->palPalEntry[iLoop].peRed)) = (WORD)iLoop; ! 251: pLogPal->palPalEntry[iLoop].peBlue = 0; ! 252: pLogPal->palPalEntry[iLoop].peFlags = PC_EXPLICIT; ! 253: } ! 254: ! 255: /* create a logical color palette according the information ! 256: * in the LOGPALETTE structure. ! 257: */ ! 258: hPal = CreatePalette ((LPLOGPALETTE) pLogPal) ; ! 259: break; ! 260: ! 261: case WM_GETMINMAXINFO: ! 262: ! 263: ((LPRGPT)lParam)->iInfo[6] = nXBorder * 2 + PALETTESIZE; ! 264: ((LPRGPT)lParam)->iInfo[7] = nXBorder * 2 + nYTitle*3; ! 265: ! 266: return DefWindowProc (hWnd, iMessage, wParam, lParam) ; ! 267: break; ! 268: ! 269: case WM_PAINT: ! 270: ! 271: /* Divide client width into equal-sized parts, one per palette ! 272: * entry, and re-calculate client width so that it will display ! 273: * exactly as many vertical bars as there are palette entries. ! 274: */ ! 275: GetClientRect(hWnd,(LPRECT) &rClientRect); ! 276: nSizeX = (rClientRect.right - rClientRect.left); ! 277: nSizeX = (nSizeX/iNumColors) * iNumColors; ! 278: ! 279: nSizeY = rClientRect.bottom - rClientRect.top; ! 280: GetWindowRect(hWnd,(LPRECT) &rClientRect); ! 281: ! 282: /* Adjust window width so that it can display exactly ! 283: * as many vertical bars( of equal width) as there are palette ! 284: * colors. ! 285: */ ! 286: ! 287: SetWindowPos( hWnd, ! 288: (HWND)NULL, ! 289: 0, ! 290: 0, ! 291: nSizeX + 2*nXBorder, ! 292: rClientRect.bottom - rClientRect.top, ! 293: SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); ! 294: ! 295: hDC = BeginPaint(hWnd, &ps); ! 296: ! 297: /* Select the palette into the window device context and ! 298: * make the Palette Manager map the logical palette to the ! 299: * system palette (realize it). ! 300: */ ! 301: SelectPalette (hDC, hPal, 1); ! 302: RealizePalette (hDC); ! 303: ! 304: /* Calculate width of each color bar to be displayed */ ! 305: nIncr = nSizeX / iNumColors; ! 306: ! 307: /* Paint the individual bars separately on the app. window */ ! 308: for (nStart = iLoop = 0; iLoop < iNumColors; iLoop++){ ! 309: ! 310: /* Since this app. uses a logical palette, use the ! 311: * PALETTEINDEX macro to specify the palette entry ! 312: * index instead of using an explicit RGB value. ! 313: */ ! 314: hBrush = CreateSolidBrush (PALETTEINDEX (iLoop)); ! 315: dwPal[iLoop] = GetNearestColor (hDC, PALETTEINDEX (iLoop) ); ! 316: hOldBrush = SelectObject (hDC,hBrush) ; ! 317: PatBlt (hDC, nStart, 0, nIncr, nSizeY, PATCOPY); ! 318: nStart += nIncr; ! 319: SelectObject (hDC, hOldBrush); ! 320: DeleteObject (hBrush) ; ! 321: } ! 322: wsprintf (szTitlebuf, "MyPal Colors= %d", iNumColors); ! 323: SetWindowText (hWnd, (LPSTR)szTitlebuf); ! 324: ! 325: EndPaint(hWnd,&ps); ! 326: ! 327: break ; ! 328: ! 329: case WM_MOUSEMOVE: ! 330: ! 331: if (wParam & MK_RBUTTON) { ! 332: ! 333: POINT pt; ! 334: ! 335: #ifdef WIN16 ! 336: /* Convert mouse position to screen coordinates */ ! 337: pt.x = LOWORD(lParam); ! 338: pt.y = HIWORD(lParam); ! 339: #else ! 340: LONG2POINT(lParam, pt); ! 341: #endif ! 342: ClientToScreen(hWnd, &pt); ! 343: ! 344: /* Get RGB value (color) of pixel under mouse coordinate */ ! 345: dwColor = GetPixel(hDCGlobal, pt.x, pt.y); ! 346: ! 347: /* If color value already exists in palette lookup table, ! 348: * obtain it's index. ! 349: */ ! 350: for (i=0 ; i < iNumColors ; i++) ! 351: if ( dwColor == dwPal[i] ) ! 352: break; ! 353: iIndex = i; ! 354: ! 355: /* If previous color value was not identical to current one, ! 356: * display color boxes on either side of title bar, ! 357: * the R, G, B values and palette index of current color. ! 358: */ ! 359: if (dwColor != dwLastColor) { ! 360: wsprintf ( szTitlebuf, ! 361: "MyPal Colors=%d Index=%d R=%3u G=%3u B=%3u", ! 362: iNumColors, ! 363: iIndex, ! 364: (WORD)(BYTE) GetRValue (dwColor), ! 365: (WORD)(BYTE) GetGValue (dwColor), ! 366: (WORD)(BYTE) GetBValue (dwColor)); ! 367: SetWindowText (hWnd, (LPSTR)szTitlebuf); ! 368: ShowColor (hWnd, hDCGlobal); ! 369: dwLastColor = dwColor; ! 370: } ! 371: } ! 372: break; ! 373: ! 374: case WM_RBUTTONDOWN: ! 375: ! 376: /* Determine number of color bar under mouse, thus the index ! 377: * of color in palette. ! 378: */ ! 379: x = LOWORD(lParam); ! 380: iIndex = (x / nIncr ); ! 381: ! 382: wsprintf ( szTitlebuf, ! 383: "MyPal Colors=%d Index=%d PalSize=%d RasterCaps:%d", ! 384: iNumColors, ! 385: iIndex, ! 386: iNumColors, ! 387: iRasterCaps ); ! 388: ! 389: SetWindowText (hWnd, (LPSTR)szTitlebuf); ! 390: ! 391: /* Set mouse capture so that subsequent WM_MOUSEMOVEs ! 392: * (with right mouse button depressed) will allow MyPal ! 393: * to display RGB info anywhere on the screen without losing ! 394: * the focus. ! 395: */ ! 396: SetCapture (hWnd); ! 397: bCaptureOn = TRUE; ! 398: hDCGlobal = GetDC(NULL); ! 399: if (hPal) { ! 400: SelectPalette (hDCGlobal, hPal, FALSE); ! 401: RealizePalette (hDCGlobal); ! 402: } ! 403: break; ! 404: ! 405: case WM_RBUTTONUP: ! 406: /* Stops displaying RGB and palette info and releases mouse ! 407: * capture ! 408: */ ! 409: ReleaseDC (NULL, hDCGlobal); ! 410: bCaptureOn = FALSE; ! 411: ReleaseCapture (); ! 412: break; ! 413: ! 414: case WM_MOVE: ! 415: /* If you have a wide column, this adds 1/2 so X is centered */ ! 416: iGlobalXOffset = LOWORD (lParam); ! 417: iGlobalYOffset = HIWORD (lParam) + nXBorder; ! 418: break; ! 419: ! 420: case WM_SIZE: ! 421: iYMiddle = (HIWORD (lParam)/2); ! 422: break; ! 423: ! 424: case WM_LBUTTONDOWN: ! 425: case WM_KEYDOWN: ! 426: ! 427: if (iMessage == WM_LBUTTONDOWN){ ! 428: /* determine which column was hit by the mouse */ ! 429: x = LOWORD(lParam); ! 430: iIndex = (x / nIncr ); ! 431: } ! 432: else{ ! 433: /* Use arrow keys to step thro' the palette entries */ ! 434: switch (wParam) { ! 435: case VK_RIGHT: ! 436: case VK_UP: ! 437: /* go to next (higher) palette entry */ ! 438: iIndex++; ! 439: break; ! 440: case VK_LEFT: ! 441: case VK_DOWN: ! 442: /* go to previous (lower) palette entry */ ! 443: iIndex--; ! 444: break; ! 445: case VK_NEXT: ! 446: iIndex += 10; ! 447: break; ! 448: case VK_PRIOR: ! 449: iIndex -= 10; ! 450: break; ! 451: case VK_HOME: ! 452: /* go to first palette entry */ ! 453: iIndex = 0; ! 454: break; ! 455: case VK_END: ! 456: /* go to last palette entry */ ! 457: iIndex = iNumColors-1; ! 458: break; ! 459: default: ! 460: return 0L; ! 461: break; ! 462: } ! 463: /* Make sure the palette index is within range else ! 464: * set it to the limiting values and give a warning beep. ! 465: */ ! 466: if (iIndex < 0) { ! 467: iIndex = 0; ! 468: MessageBeep(1); ! 469: } ! 470: else{ ! 471: if (iIndex > iNumColors-1) { ! 472: iIndex = iNumColors-1; ! 473: MessageBeep(1); ! 474: } ! 475: } ! 476: ! 477: pt.x = (SHORT)((iIndex * nIncr) + ! 478: iGlobalXOffset + ! 479: ((nIncr > 1) ? (nIncr / 2) : 1)); ! 480: pt.y = (SHORT)(iYMiddle + iGlobalYOffset); ! 481: ! 482: SetCursorPos (pt.x, pt.y); ! 483: } ! 484: ! 485: if (TRUE == bCaptureOn) { ! 486: MessageBeep(1); ! 487: break; ! 488: } ! 489: ! 490: /* Select & realize the palette or the colors > 0x7 ! 491: * will not match up. ! 492: */ ! 493: hDC = GetDC(NULL); ! 494: SelectPalette (hDC, hPal, 1); ! 495: RealizePalette (hDC) ; ! 496: ! 497: dwColor = GetNearestColor (hDC, PALETTEINDEX (iIndex)); ! 498: ! 499: wsprintf ( szTitlebuf, ! 500: "MyPal Colors=%d Index=%d R=%3u G=%3u B=%3u", ! 501: iNumColors, ! 502: iIndex, ! 503: (WORD)(BYTE)GetRValue (dwColor), ! 504: (WORD)(BYTE)GetGValue (dwColor), ! 505: (WORD)(BYTE)GetBValue (dwColor) ! 506: ); ! 507: ! 508: SetWindowText (hWnd, (LPSTR)szTitlebuf); ! 509: ShowColor (hWnd,hDC); ! 510: ReleaseDC(NULL, hDC); ! 511: break; ! 512: ! 513: default: ! 514: return DefWindowProc (hWnd, iMessage, wParam, lParam) ; ! 515: ! 516: } ! 517: return 0L ; ! 518: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.