MYPAL.C
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:22k
源码类别:
Windows编程
开发平台:
Visual C++
- /******************************************************************************
- * This is a part of the Microsoft Source Code Samples.
- * Copyright (C) 1993-1997 Microsoft Corporation.
- * All rights reserved.
- * This source code is only intended as a supplement to
- * Microsoft Development Tools and/or WinHelp documentation.
- * See these sources for detailed information regarding the
- * Microsoft samples programs.
- ******************************************************************************/
- /***************************************************************************
- * *
- * PROGRAM : MyPal.c *
- * *
- * PURPOSE : Sets up a bar representation of the current physical *
- * palette and displays useful information regarding *
- * pixel colors and palette indices. *
- * *
- * FUNCTIONS : WinMain() - calls initialization function, *
- * processes message loop *
- * *
- * WndProc() - Window function for app. Processes *
- * window messages. *
- * *
- * ShowColor() - Displays a little box on each side of the *
- * caption bar displaying the pixel color at the*
- * mouse position. *
- ***************************************************************************/
- #include <windows.h>
- #include "mypal.h"
- HANDLE hPal; /* Handle to the application's logical palette */
- static INT nSizeX; /* Width of the application window */
- static INT nSizeY; /* Height of the application window */
- NPLOGPALETTE pLogPal; /* Pointer to program's logical palette */
- INT nXBorder; /* Width of window border */
- INT nXTitle; /* Width of title bar */
- INT nYTitle; /* Height of title bar */
- BOOL bCaptureOn; /* Indicates if mouse capture is on */
- INT iIndex; /* Last index selected in palette */
- CHAR szTitlebuf[90];/* Buffer for pixel and palette info. text */
- HDC hDCGlobal; /* The Screen DC */
- INT iNumColors; /* Number of colors supported by device */
- INT iRasterCaps; /* Raster capabilities */
- RECT rClientRect; /* Client rectangle coordinates */
- DWORD dwPal[PALETTESIZE]; /* Stores palette entries for later lookup */
- INT iGlobalXOffset;
- INT iGlobalYOffset;
- INT iYMiddle;
- LONG APIENTRY WndProc(HWND hWnd, UINT iMessage, UINT wParam, LONG lParam);
- /****************************************************************************
- * *
- * FUNCTION : void ShowColor(HWND hWnd, HDC hDC) *
- * *
- * PURPOSE : Displays a little box on each side of the caption bar *
- * displaying the pixel color at the mouse position. *
- * *
- ****************************************************************************/
- VOID ShowColor (
- HWND hWnd,
- HDC hDC)
- {
- HBRUSH hBrush, hOldBrush;
- hBrush = CreateSolidBrush ( PALETTEINDEX(iIndex) );
- hOldBrush = SelectObject (hDC,hBrush) ;
- GetWindowRect (hWnd, (LPRECT)&rClientRect);
- PatBlt ( hDC,
- rClientRect.left + nXTitle + nXBorder + 1,
- rClientRect.top + nXBorder,
- nXTitle,
- nYTitle,
- PATCOPY);
- PatBlt(hDC,
- rClientRect.right - ( 3 * nXTitle + nXBorder + 2),
- rClientRect.top + nXBorder,
- nXTitle,
- nYTitle,
- PATCOPY);
- SelectObject (hDC, hOldBrush);
- DeleteObject (hBrush) ;
- }
- /****************************************************************************
- * *
- * FUNCTION : WinMain(HANDLE, HANDLE, LPSTR, int) *
- * *
- * PURPOSE : Creates the app. window and processes the message loop. *
- * *
- ****************************************************************************/
- int APIENTRY WinMain(
- HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow
- )
- {
- static CHAR szAppName [] = "MyPal";
- HWND hWnd;
- WNDCLASS wndclass;
- MSG msg ;
- INT xScreen;
- INT yScreen;
- UNREFERENCED_PARAMETER( lpCmdLine );
- if (!hPrevInstance){
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = (WNDPROC) WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon(hInstance, szAppName);
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
- wndclass.hbrBackground = GetStockObject (BLACK_BRUSH);
- wndclass.lpszMenuName = szAppName;
- wndclass.lpszClassName = szAppName;
- if (!RegisterClass (&wndclass))
- return FALSE ;
- }
- /* Do some global initializations */
- xScreen = GetSystemMetrics (SM_CXSCREEN);
- yScreen = GetSystemMetrics (SM_CYSCREEN);
- nXBorder = (INT)GetSystemMetrics (SM_CXFRAME);
- nXTitle = (INT)GetSystemMetrics (SM_CXSIZE);
- nYTitle = (INT)GetSystemMetrics (SM_CYSIZE);
- iIndex = 0;
- bCaptureOn = FALSE;
- hDCGlobal = GetDC (NULL);
- iRasterCaps = GetDeviceCaps(hDCGlobal, RASTERCAPS);
- iRasterCaps = (iRasterCaps & RC_PALETTE) ? TRUE : FALSE;
- if (iRasterCaps)
- iNumColors = GetDeviceCaps(hDCGlobal, SIZEPALETTE);
- else
- iNumColors = GetDeviceCaps( hDCGlobal, NUMCOLORS);
- ReleaseDC (NULL,hDCGlobal);
- nSizeX = ((xScreen - 2*nXBorder) / PALETTESIZE) * PALETTESIZE;
- /* create the app. window */
- hWnd = CreateWindow (szAppName,
- "My Physical Palette ",
- WS_OVERLAPPEDWINDOW,
- (xScreen-nSizeX) / 2 - nXBorder,
- yScreen - ( 4 * GetSystemMetrics (SM_CYCAPTION)),
- nSizeX + 2 * nXBorder,
- 4 * GetSystemMetrics (SM_CYCAPTION),
- NULL,
- NULL,
- hInstance,
- NULL);
- ShowWindow (hWnd, nCmdShow);
- UpdateWindow (hWnd);
- while (GetMessage (&msg, NULL, 0, 0)){
- TranslateMessage (&msg) ;
- DispatchMessage (&msg) ;
- }
- return msg.wParam ;
- }
- /******************************************************************************
- * *
- * FUNCTION: WndProc(HWND, unsigned, WORD, LONG) *
- * *
- * PURPOSE: Processes window messages and sets up a 256 bar representation *
- * of the current physical palette. Specifically, in response to: *
- * *
- * WM_CREATE -Allocates for and sets up a LOGPALETTE *
- * structure, creates a logical palette the same *
- * size as the physical palette and obtains a *
- * handle to the logical palette. *
- * *
- * WM_DESTROY -Destroys the logical palette and shuts down app. *
- * *
- * WM_PAINT -Resizes client area to hold as many vertical *
- * color bars as there are physical palette entries.*
- * Also realises the current logical palette and *
- * draws one color bar corresponding to each *
- * palette entry *
- * *
- * WM_RBUTTONDOWN -Captures the mouse and initiates the below *
- * process: *
- * *
- * WM_MOUSEMOVE -Following a WM_RBUTTONDOWN, if the right mouse *
- * key is depressed, displays info about the *
- * pixel RGB value and palette index of the mouse *
- * coordinates. *
- * *
- * WM_RBUTTONUP -Release mouse capture and terminates the above *
- * process *
- * *
- * WM_LBUTTONDOWN -Determines and displays the palette index and *
- * RGB value of the bar under the mouse. *
- * *
- * WM_KEYDOWN -Allows use of the arrow keys in stepping thro' *
- * palette entries. *
- * *
- *****************************************************************************/
- LONG APIENTRY WndProc (
- HWND hWnd,
- UINT iMessage,
- UINT wParam,
- LONG lParam)
- {
- HDC hDC;
- PAINTSTRUCT ps;
- INT iLoop;
- INT nStart;
- HBRUSH hBrush;
- HBRUSH hOldBrush;
- MPOINT pt;
- static INT nIncr;
- static DWORD dwColor;
- static DWORD dwLastColor;
- static INT i, x;
- switch (iMessage) {
- case WM_DESTROY:
- /* delete the handle to the logical palette if it has any
- * color entries and quit.
- */
- if (pLogPal->palNumEntries)
- DeleteObject (hPal);
- PostQuitMessage (0) ;
- break ;
- case WM_CREATE:
- /* Allocate enough memory for a logical palette with
- * PALETTESIZE entries and set the size and version fields
- * of the logical palette structure.
- */
- pLogPal = (NPLOGPALETTE) LocalAlloc (LMEM_FIXED,
- (sizeof (LOGPALETTE) +
- (sizeof (PALETTEENTRY) * (PALETTESIZE))));
- if(!pLogPal){
- MessageBox(hWnd, "<WM_CREATE> Not enough memory for palette.", NULL, MB_OK | MB_ICONHAND);
- PostQuitMessage (0) ;
- break;
- }
- pLogPal->palVersion = 0x300;
- pLogPal->palNumEntries = PALETTESIZE;
- /* fill in intensities for all palette entry colors */
- for (iLoop = 0; iLoop < PALETTESIZE; iLoop++) {
- *((WORD *) (&pLogPal->palPalEntry[iLoop].peRed)) = (WORD)iLoop;
- pLogPal->palPalEntry[iLoop].peBlue = 0;
- pLogPal->palPalEntry[iLoop].peFlags = PC_EXPLICIT;
- }
- /* create a logical color palette according the information
- * in the LOGPALETTE structure.
- */
- hPal = CreatePalette ((LPLOGPALETTE) pLogPal) ;
- break;
- case WM_GETMINMAXINFO:
- ((LPRGPT)lParam)->iInfo[6] = nXBorder * 2 + PALETTESIZE;
- ((LPRGPT)lParam)->iInfo[7] = nXBorder * 2 + nYTitle*3;
- return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
- break;
- case WM_PAINT:
- /* Divide client width into equal-sized parts, one per palette
- * entry, and re-calculate client width so that it will display
- * exactly as many vertical bars as there are palette entries.
- */
- GetClientRect(hWnd,(LPRECT) &rClientRect);
- nSizeX = (rClientRect.right - rClientRect.left);
- nSizeX = (nSizeX/iNumColors) * iNumColors;
- nSizeY = rClientRect.bottom - rClientRect.top;
- GetWindowRect(hWnd,(LPRECT) &rClientRect);
- /* Adjust window width so that it can display exactly
- * as many vertical bars( of equal width) as there are palette
- * colors.
- */
- SetWindowPos( hWnd,
- (HWND)NULL,
- 0,
- 0,
- nSizeX + 2*nXBorder,
- rClientRect.bottom - rClientRect.top,
- SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
- hDC = BeginPaint(hWnd, &ps);
- /* Select the palette into the window device context and
- * make the Palette Manager map the logical palette to the
- * system palette (realize it).
- */
- SelectPalette (hDC, hPal, 1);
- RealizePalette (hDC);
- /* Calculate width of each color bar to be displayed */
- nIncr = nSizeX / iNumColors;
- /* Paint the individual bars separately on the app. window */
- for (nStart = iLoop = 0; iLoop < iNumColors; iLoop++){
- /* Since this app. uses a logical palette, use the
- * PALETTEINDEX macro to specify the palette entry
- * index instead of using an explicit RGB value.
- */
- hBrush = CreateSolidBrush (PALETTEINDEX (iLoop));
- dwPal[iLoop] = GetNearestColor (hDC, PALETTEINDEX (iLoop) );
- hOldBrush = SelectObject (hDC,hBrush) ;
- PatBlt (hDC, nStart, 0, nIncr, nSizeY, PATCOPY);
- nStart += nIncr;
- SelectObject (hDC, hOldBrush);
- DeleteObject (hBrush) ;
- }
- wsprintf (szTitlebuf, "MyPal Colors= %d", iNumColors);
- SetWindowText (hWnd, (LPSTR)szTitlebuf);
- EndPaint(hWnd,&ps);
- break ;
- case WM_MOUSEMOVE:
- if (wParam & MK_RBUTTON) {
- POINT pt;
- #ifdef WIN16
- /* Convert mouse position to screen coordinates */
- pt.x = LOWORD(lParam);
- pt.y = HIWORD(lParam);
- #else
- LONG2POINT(lParam, pt);
- #endif
- ClientToScreen(hWnd, &pt);
- /* Get RGB value (color) of pixel under mouse coordinate */
- dwColor = GetPixel(hDCGlobal, pt.x, pt.y);
- /* If color value already exists in palette lookup table,
- * obtain it's index.
- */
- for (i=0 ; i < iNumColors ; i++)
- if ( dwColor == dwPal[i] )
- break;
- iIndex = i;
- /* If previous color value was not identical to current one,
- * display color boxes on either side of title bar,
- * the R, G, B values and palette index of current color.
- */
- if (dwColor != dwLastColor) {
- wsprintf ( szTitlebuf,
- "MyPal Colors=%d Index=%d R=%3u G=%3u B=%3u",
- iNumColors,
- iIndex,
- (WORD)(BYTE) GetRValue (dwColor),
- (WORD)(BYTE) GetGValue (dwColor),
- (WORD)(BYTE) GetBValue (dwColor));
- SetWindowText (hWnd, (LPSTR)szTitlebuf);
- ShowColor (hWnd, hDCGlobal);
- dwLastColor = dwColor;
- }
- }
- break;
- case WM_RBUTTONDOWN:
- /* Determine number of color bar under mouse, thus the index
- * of color in palette.
- */
- x = LOWORD(lParam);
- iIndex = (x / nIncr );
- wsprintf ( szTitlebuf,
- "MyPal Colors=%d Index=%d PalSize=%d RasterCaps:%d",
- iNumColors,
- iIndex,
- iNumColors,
- iRasterCaps );
- SetWindowText (hWnd, (LPSTR)szTitlebuf);
- /* Set mouse capture so that subsequent WM_MOUSEMOVEs
- * (with right mouse button depressed) will allow MyPal
- * to display RGB info anywhere on the screen without losing
- * the focus.
- */
- SetCapture (hWnd);
- bCaptureOn = TRUE;
- hDCGlobal = GetDC(NULL);
- if (hPal) {
- SelectPalette (hDCGlobal, hPal, FALSE);
- RealizePalette (hDCGlobal);
- }
- break;
- case WM_RBUTTONUP:
- /* Stops displaying RGB and palette info and releases mouse
- * capture
- */
- ReleaseDC (NULL, hDCGlobal);
- bCaptureOn = FALSE;
- ReleaseCapture ();
- break;
- case WM_MOVE:
- /* If you have a wide column, this adds 1/2 so X is centered */
- iGlobalXOffset = LOWORD (lParam);
- iGlobalYOffset = HIWORD (lParam) + nXBorder;
- break;
- case WM_SIZE:
- iYMiddle = (HIWORD (lParam)/2);
- break;
- case WM_LBUTTONDOWN:
- case WM_KEYDOWN:
- if (iMessage == WM_LBUTTONDOWN){
- /* determine which column was hit by the mouse */
- x = LOWORD(lParam);
- iIndex = (x / nIncr );
- }
- else{
- /* Use arrow keys to step thro' the palette entries */
- switch (wParam) {
- case VK_RIGHT:
- case VK_UP:
- /* go to next (higher) palette entry */
- iIndex++;
- break;
- case VK_LEFT:
- case VK_DOWN:
- /* go to previous (lower) palette entry */
- iIndex--;
- break;
- case VK_NEXT:
- iIndex += 10;
- break;
- case VK_PRIOR:
- iIndex -= 10;
- break;
- case VK_HOME:
- /* go to first palette entry */
- iIndex = 0;
- break;
- case VK_END:
- /* go to last palette entry */
- iIndex = iNumColors-1;
- break;
- default:
- return 0L;
- break;
- }
- /* Make sure the palette index is within range else
- * set it to the limiting values and give a warning beep.
- */
- if (iIndex < 0) {
- iIndex = 0;
- MessageBeep(1);
- }
- else{
- if (iIndex > iNumColors-1) {
- iIndex = iNumColors-1;
- MessageBeep(1);
- }
- }
- pt.x = (SHORT)((iIndex * nIncr) +
- iGlobalXOffset +
- ((nIncr > 1) ? (nIncr / 2) : 1));
- pt.y = (SHORT)(iYMiddle + iGlobalYOffset);
- SetCursorPos (pt.x, pt.y);
- }
- if (TRUE == bCaptureOn) {
- MessageBeep(1);
- break;
- }
- /* Select & realize the palette or the colors > 0x7
- * will not match up.
- */
- hDC = GetDC(NULL);
- SelectPalette (hDC, hPal, 1);
- RealizePalette (hDC) ;
- dwColor = GetNearestColor (hDC, PALETTEINDEX (iIndex));
- wsprintf ( szTitlebuf,
- "MyPal Colors=%d Index=%d R=%3u G=%3u B=%3u",
- iNumColors,
- iIndex,
- (WORD)(BYTE)GetRValue (dwColor),
- (WORD)(BYTE)GetGValue (dwColor),
- (WORD)(BYTE)GetBValue (dwColor)
- );
- SetWindowText (hWnd, (LPSTR)szTitlebuf);
- ShowColor (hWnd,hDC);
- ReleaseDC(NULL, hDC);
- break;
- default:
- return DefWindowProc (hWnd, iMessage, wParam, lParam) ;
- }
- return 0L ;
- }