/******************************************************************************\ * 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: Demo.c PURPOSE: Demonstrates how to manipulate a cursor and select a region FUNCTIONS: WinMain() - calls initialization function, processes message loop DemoInit() - initializes window data and registers window DemoWndProc() - processes messages About() - processes messages for "About" dialog box COMMENTS: This code is a modified version of the CURSOR.C program. Instead of using inline code for drawing the shape, the routines from the Select library are called. ****************************************************************************/ #include "windows.h" #include "demo.h" #include "select.h" HANDLE hInst; BOOL bTrack = FALSE; INT OrgX = 0, OrgY = 0; INT PrevX = 0, PrevY = 0; INT X = 0, Y = 0; RECT Rect; INT Shape = SL_BLOCK; /* Shape to use for rectangle */ BOOL RetainShape = FALSE; /* Retain or destroy shape */ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hWnd; MSG msg; CHAR szAppName[64]; UNREFERENCED_PARAMETER(lpCmdLine); if (!hPrevInstance) if (!DemoInit(hInstance)) return (0); hInst = hInstance; LoadString(hInstance, IDS_APPNAME, szAppName, sizeof(szAppName)); hWnd = CreateWindow("Demo", szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); if (!hWnd) return (0); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (msg.wParam); } /**************************************************************************** FUNCTION: DemoInit(HANDLE) PURPOSE: Initializes window data and registers window class ****************************************************************************/ BOOL DemoInit(HANDLE hInstance) { HANDLE hMemory; PWNDCLASS pWndClass; BOOL bSuccess; CHAR lpBuffer[128]; hMemory = LocalAlloc(LPTR, sizeof(WNDCLASS)); if(!hMemory){ LoadString(hInst, IDS_NOMEM, lpBuffer, sizeof(lpBuffer)); MessageBox(NULL, lpBuffer, NULL, MB_OK | MB_ICONHAND); return(FALSE); } pWndClass = (PWNDCLASS) LocalLock(hMemory); pWndClass->hCursor = LoadCursor(NULL, IDC_ARROW); pWndClass->hIcon = LoadIcon(NULL, IDI_APPLICATION); pWndClass->lpszMenuName = (LPSTR) "Menu"; pWndClass->lpszClassName = (LPSTR) "Demo"; pWndClass->hbrBackground = GetStockObject(WHITE_BRUSH); pWndClass->hInstance = hInstance; pWndClass->style = 0; pWndClass->lpfnWndProc = (WNDPROC)DemoWndProc; bSuccess = RegisterClass(pWndClass); LocalUnlock(hMemory); LocalFree(hMemory); return (bSuccess); } /**************************************************************************** FUNCTION: DemoWndProc(HWND, unsigned, WORD, LONG) PURPOSE: Processes messages MESSAGES: WM_SYSCOMMAND - system menu (About dialog box) WM_CREATE - create window WM_DESTROY - destroy window WM_LBUTTONDOWN - left mouse button WM_MOUSEMOVE - mouse movement WM_LBUTTONUP - left button released WM_COMMAND messages: IDM_BOX - use inverted box for selecting a region IDM_BLOCK - use empty box for selecting a region IDM_RETAIN - retain/delete selection on button release COMMENTS: When the left mouse button is pressed, btrack is set to TRUE so that the code for WM_MOUSEMOVE will keep track of the mouse and update the box accordingly. Once the button is released, btrack is set to FALSE, and the current position is saved. Holding the SHIFT key while pressing the left button will extend the current box rather then erasing it and starting a new one. The exception is when the retain shape option is enabled. With this option, the rectangle is zeroed whenever the mouse is released so that it can not be erased or extended. ****************************************************************************/ LONG APIENTRY DemoWndProc( HWND hWnd, UINT message, UINT wParam, LONG lParam) { FARPROC lpProcAbout; HMENU hMenu; switch (message) { case WM_COMMAND: // LOWORD added for portability switch (LOWORD(wParam)) { case IDM_BOX: Shape = SL_BOX; hMenu = GetMenu(hWnd); CheckMenuItem(hMenu, IDM_BOX, MF_CHECKED); CheckMenuItem(hMenu, IDM_BLOCK, MF_UNCHECKED); break; case IDM_BLOCK: Shape = SL_BLOCK; hMenu = GetMenu(hWnd); CheckMenuItem(hMenu, IDM_BOX, MF_UNCHECKED); CheckMenuItem(hMenu, IDM_BLOCK, MF_CHECKED); break; case IDM_RETAIN: if (RetainShape) { hMenu = GetMenu(hWnd); CheckMenuItem(hMenu, IDM_RETAIN, MF_UNCHECKED); RetainShape = FALSE; } else { hMenu = GetMenu(hWnd); CheckMenuItem(hMenu, IDM_RETAIN, MF_CHECKED); RetainShape = TRUE; } break; case IDM_ABOUT: lpProcAbout = MakeProcInstance((FARPROC)About, hInst); DialogBox(hInst, "AboutBox", hWnd, (DLGPROC)lpProcAbout); FreeProcInstance(lpProcAbout); break; } break; case WM_LBUTTONDOWN: bTrack = TRUE; /* user has pressed the left button */ /* If you don't want the shape cleared, you must clear the Rect * coordinates before calling StartSelection */ if (RetainShape) SetRectEmpty(&Rect); StartSelection(hWnd, MAKEMPOINT(lParam), &Rect, (wParam & MK_SHIFT) ? SL_EXTEND | Shape : Shape); break; case WM_MOUSEMOVE: if (bTrack) UpdateSelection(hWnd, MAKEMPOINT(lParam), &Rect, Shape); break; case WM_LBUTTONUP: if (bTrack) EndSelection(MAKEMPOINT(lParam), &Rect); bTrack = FALSE; break; case WM_SIZE: switch (wParam) { case SIZEICONIC: /* If we aren't in retain mode we want to clear the * current rectangle now! */ if (!RetainShape) SetRectEmpty(&Rect); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, message, wParam, lParam)); } return (0); } /**************************************************************************** FUNCTION: About(HWND, unsigned, WORD, LONG) PURPOSE: Processes messages for "About" dialog box MESSAGES: WM_INITDIALOG - initialize dialog box WM_COMMAND - Input received ****************************************************************************/ BOOL APIENTRY About( HWND hDlg, UINT message, UINT wParam, LONG lParam) { switch (message) { case WM_INITDIALOG: return (TRUE); case WM_COMMAND: // LOWORD added for portability if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, TRUE); return (TRUE); } return (TRUE); } return (FALSE); UNREFERENCED_PARAMETER(lParam); }