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