SCRAWL.CPP
资源名称:MSDN_VC98.zip [点击查看]
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:31k
源码类别:
Windows编程
开发平台:
Visual C++
- /**************************************************************************
- SCRAWL.CPP - A dumb drawing app demo for DirectInput
- Collects mouse data in various modes to demonstrate how it's done.
- **************************************************************************/
- /**************************************************************************
- (C) Copyright 1995-1997 Microsoft Corp. All rights reserved.
- You have a royalty-free right to use, modify, reproduce and
- distribute the Sample Files (and/or any modified version) in
- any way you find useful, provided that you agree that
- Microsoft has no warranty obligations or liability for any
- Sample Application Files which are modified.
- **************************************************************************/
- #include <windows.h>
- #include <windowsx.h>
- #include <stdarg.h>
- #define DIRECTINPUT_VERSION 0x0300 /* Remain DX3-compatible */
- #include <dinput.h>
- #include "scrawl.h"
- /****************************************************************************
- *
- * This is an incredibly dump app. It just lets you "draw" on
- * a monochrome bitmap via DirectInput. The purpose is not to
- * dazzle you with mind-altering brilliance. It's just to show
- * how to use the DirectInput mouse interface.
- *
- ****************************************************************************/
- /****************************************************************************
- *
- * Manifest constants
- *
- ****************************************************************************/
- #define DINPUT_BUFFERSIZE 16
- #define DINPUT_CXBITMAP 512
- #define DINPUT_CYBITMAP 300
- /****************************************************************************
- *
- * Global variables
- *
- ****************************************************************************/
- const char c_szAppName[] = "Scrawl"; /* My name */
- HINSTANCE g_hinst; /* My instance handle */
- BOOL g_fActive; /* Am I the active window? */
- int g_x = DINPUT_CXBITMAP / 2; /* Virtual x-coordinate */
- int g_y = DINPUT_CYBITMAP / 2; /* Virtual y-coordinate */
- int g_dxFuzz; /* Leftover x-fuzz from scaling */
- int g_dyFuzz; /* Leftover y-fuzz from scaling */
- int g_iSensitivity; /* Mouse sensitivity */
- HDC g_hdc; /* Memory DC our picture lives in */
- HBITMAP g_hbm; /* Our picture */
- HBITMAP g_hbmDeselect; /* Stock bitmap for deselecting */
- HCURSOR g_hcurCross; /* Crosshairs */
- int g_cxCross; /* Width of crosshairs cursor */
- int g_cyCross; /* Height of crosshairs cursor */
- int g_dxCrossHot; /* Hotspot location of crosshairs */
- int g_dyCrossHot; /* Hotspot location of crosshairs */
- int g_fShowCursor = 1; /* Should the cursor be shown? */
- /****************************************************************************
- *
- * DirectInput globals
- *
- ****************************************************************************/
- LPDIRECTINPUT g_pdi;
- LPDIRECTINPUTDEVICE g_pMouse;
- HANDLE g_hevtMouse;
- /****************************************************************************
- *
- * Complain
- *
- * Whine and moan.
- *
- ****************************************************************************/
- void CDECL
- Complain(HWND hwndOwner, HRESULT hr, LPCSTR pszFormat, ...)
- {
- va_list ap;
- char szBuf[1024];
- char *pszBuf;
- va_start(ap, pszFormat);
- pszBuf = szBuf + wsprintf(szBuf, pszFormat, ap);
- va_end(ap);
- wsprintf(pszBuf, "nnError = %08x", hr);
- MessageBox(hwndOwner, szBuf, c_szAppName, MB_OK);
- }
- /****************************************************************************
- *
- * DIInit
- *
- * Initialize the DirectInput variables.
- *
- ****************************************************************************/
- BOOL DIInit(HWND hwnd)
- {
- HRESULT hr;
- /*
- * Register with DirectInput and get an IDirectInput to play with.
- */
- hr = DirectInputCreate(g_hinst, DIRECTINPUT_VERSION, &g_pdi, NULL);
- if (FAILED(hr)) {
- Complain(hwnd, hr, "DirectInputCreate");
- return FALSE;
- }
- /*
- * Obtain an interface to the system mouse device.
- */
- hr = g_pdi->CreateDevice(GUID_SysMouse, &g_pMouse, NULL);
- if (FAILED(hr)) {
- Complain(hwnd, hr, "CreateDevice(SysMouse)");
- return FALSE;
- }
- /*
- * Set the data format to "mouse format".
- */
- hr = g_pMouse->SetDataFormat(&c_dfDIMouse);
- if (FAILED(hr)) {
- Complain(hwnd, hr, "SetDataFormat(SysMouse, dfDIMouse)");
- return FALSE;
- }
- /*
- * Set the cooperativity level.
- */
- hr = g_pMouse->SetCooperativeLevel(hwnd,
- DISCL_EXCLUSIVE | DISCL_FOREGROUND);
- if (FAILED(hr)) {
- Complain(hwnd, hr, "SetCooperativeLevel(SysMouse)");
- return FALSE;
- }
- /*
- * Create the handle that tells us new data is available.
- */
- g_hevtMouse = CreateEvent(0, 0, 0, 0);
- if (g_hevtMouse == NULL) {
- Complain(hwnd, GetLastError(), "CreateEvent");
- return FALSE;
- }
- /*
- * Associate the event with the device.
- */
- hr = g_pMouse->SetEventNotification(g_hevtMouse);
- if (FAILED(hr)) {
- Complain(hwnd, hr, "SetEventNotification(SysMouse)");
- return FALSE;
- }
- /*
- * Set the buffer size to DINPUT_BUFFERSIZE elements.
- * The buffer size is a DWORD property associated with the device.
- */
- DIPROPDWORD dipdw =
- {
- {
- sizeof(DIPROPDWORD), // diph.dwSize
- sizeof(DIPROPHEADER), // diph.dwHeaderSize
- 0, // diph.dwObj
- DIPH_DEVICE, // diph.dwHow
- },
- DINPUT_BUFFERSIZE, // dwData
- };
- hr = g_pMouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);
- if (FAILED(hr)) {
- Complain(hwnd, hr, "Set buffer size(SysMouse)");
- return FALSE;
- }
- return TRUE;
- }
- /****************************************************************************
- *
- * DITerm
- *
- * Terminate our usage of DirectInput.
- *
- ****************************************************************************/
- void DITerm(void)
- {
- if (g_pdi) g_pdi ->Release(), g_pdi = NULL;
- if (g_pMouse) g_pMouse->Release(), g_pMouse = NULL;
- if (g_hevtMouse) CloseHandle(g_hevtMouse), g_hevtMouse = NULL;
- }
- /****************************************************************************
- *
- * InvalidateCursorRect
- *
- * Invalidate the rectangle that contains the cursor.
- *
- * The coordinates are in client coordinates.
- *
- ****************************************************************************/
- void InvalidateCursorRect(HWND hwnd)
- {
- RECT rc = { g_x - g_dxCrossHot, g_y - g_dyCrossHot,
- g_x - g_dxCrossHot + g_cxCross, g_y - g_dyCrossHot + g_cyCross };
- InvalidateRect(hwnd, &rc, 0);
- }
- /****************************************************************************
- *
- * UpdateCursorPosition
- *
- * Move our private cursor in the requested direction, subject
- * to clipping, scaling, and all that other stuff.
- *
- * This does not redraw the cursor. You need to do that yourself.
- *
- ****************************************************************************/
- void UpdateCursorPosition(int dx, int dy)
- {
- /*
- * Pick up any leftover fuzz from last time. This is important
- * when scaling down mouse motions. Otherwise, the user can
- * drag to the right extremely slow for the length of the table
- * and not get anywhere.
- */
- dx += g_dxFuzz; g_dxFuzz = 0;
- dy += g_dyFuzz; g_dyFuzz = 0;
- switch (g_iSensitivity) {
- case 1: /* High sensitivity: Magnify! */
- dx *= 2;
- dy *= 2;
- break;
- case -1: /* Low sensitivity: Scale down */
- g_dxFuzz = dx % 2; /* remember the fuzz for next time */
- g_dyFuzz = dy % 2;
- dx /= 2;
- dy /= 2;
- break;
- default:
- case 0: /* No sensitivity */
- ; /* No adjustments needed */
- }
- g_x += dx;
- g_y += dy;
- /* Clip the cursor to our client area */
- if (g_x < 0) g_x = 0;
- if (g_x >= DINPUT_CXBITMAP) g_x = DINPUT_CXBITMAP - 1;
- if (g_y < 0) g_y = 0;
- if (g_y >= DINPUT_CYBITMAP) g_y = DINPUT_CYBITMAP - 1;
- }
- /****************************************************************************
- *
- * Scrawl_SyncAcquire
- *
- * Acquire or unacquire the devices, depending on the the g_fActive
- * flag. This synchronizes the devices with our internal view of
- * the world.
- *
- * Also repaint the cursor so that it hides/shows in sync with
- * acquisition.
- *
- ****************************************************************************/
- void
- Scrawl_SyncAcquire(HWND hwnd)
- {
- if (g_fActive) {
- if (g_pMouse) g_pMouse->Acquire();
- } else {
- if (g_pMouse) g_pMouse->Unacquire();
- }
- InvalidateCursorRect(hwnd);
- }
- /****************************************************************************
- *
- * Private messages
- *
- * WM_SYNCACQUIRE forces us to re-synchronize our acquisition
- * with the world.
- *
- ****************************************************************************/
- #define WM_SYNCACQUIRE (WM_USER + 0)
- /****************************************************************************
- *
- * Scrawl_OnClear
- *
- * Wipe out the bitmap.
- *
- ****************************************************************************/
- void Scrawl_OnClear(HWND hwnd)
- {
- /*
- * Start out all white.
- */
- PatBlt(g_hdc, 0, 0, DINPUT_CXBITMAP, DINPUT_CYBITMAP, WHITENESS);
- if (hwnd) {
- InvalidateRect(hwnd, 0, 0);
- }
- }
- /****************************************************************************
- *
- * Scrawl_OnCreate
- *
- * Set up the window by appending our custom commands to the System
- * menu.
- *
- * Also disable the menu items we don't want to see.
- *
- ****************************************************************************/
- BOOL Scrawl_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
- {
- HMENU hmenu = GetSystemMenu(hwnd, FALSE);
- EnableMenuItem(hmenu, SC_SIZE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
- EnableMenuItem(hmenu, SC_MAXIMIZE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
- AppendMenu(hmenu, MF_ENABLED | MF_STRING, IDC_CLEAR, "C&leartDel");
- AppendMenu(hmenu, MF_ENABLED | MF_STRING, IDC_ABOUT, "&AbouttF1");
- AppendMenu(hmenu, MF_ENABLED | MF_STRING | MF_POPUP,
- (UINT)LoadMenu(g_hinst,
- MAKEINTRESOURCE(IDM_SENSITIVITY)),
- "Sensitivit&y");
- return 1;
- }
- /****************************************************************************
- *
- * Scrawl_OnInitMenuPopup
- *
- * Initialize the sensitivity item accordingly.
- *
- ****************************************************************************/
- void
- Scrawl_OnInitMenuPopup(HWND hwnd, HMENU hmenu, UINT item, BOOL fSystemMenu)
- {
- int iSensitivity;
- for (iSensitivity = -1; iSensitivity <= 1; iSensitivity++) {
- if (g_iSensitivity == iSensitivity) {
- CheckMenuItem(hmenu, IDC_SENSITIVITY_NORMAL + iSensitivity,
- MF_BYCOMMAND | MF_CHECKED);
- } else {
- CheckMenuItem(hmenu, IDC_SENSITIVITY_NORMAL + iSensitivity,
- MF_BYCOMMAND | MF_UNCHECKED);
- }
- }
- }
- /****************************************************************************
- *
- * Scrawl_OnKeyDown
- *
- * See if it's one of our accelerators.
- *
- ****************************************************************************/
- void Scrawl_OnKeyDown(HWND hwnd, UINT vk, BOOL fDown, int cRepeat, UINT flags)
- {
- switch (vk) {
- case '1':
- case '2':
- case '3':
- PostMessage(hwnd, WM_SYSCOMMAND, IDC_SENSITIVITY_NORMAL +
- vk - '2', 0);
- break;
- case VK_DELETE:
- PostMessage(hwnd, WM_SYSCOMMAND, IDC_CLEAR, 0);
- break;
- case VK_F1:
- PostMessage(hwnd, WM_SYSCOMMAND, IDC_ABOUT, 0);
- break;
- }
- }
- /****************************************************************************
- *
- * Scrawl_OnPaint
- *
- * Blt out our bitmap and draw our cursor on top of it.
- *
- ****************************************************************************/
- void
- Scrawl_OnPaint(HWND hwnd)
- {
- PAINTSTRUCT ps;
- HDC hdc = BeginPaint(hwnd, &ps);
- if (hdc) {
- BitBlt(hdc,
- ps.rcPaint.left,
- ps.rcPaint.top,
- ps.rcPaint.right - ps.rcPaint.left,
- ps.rcPaint.bottom - ps.rcPaint.top,
- g_hdc,
- ps.rcPaint.left,
- ps.rcPaint.top,
- SRCCOPY);
- if (g_fActive && g_fShowCursor) {
- DrawIcon(hdc, g_x - g_dxCrossHot,
- g_y - g_dyCrossHot, g_hcurCross);
- }
- EndPaint(hwnd, &ps);
- }
- }
- /****************************************************************************
- *
- * Scrawl_OnButton0Down_FlushMotion
- *
- * Flush out any motion that we are holding.
- *
- ****************************************************************************/
- typedef struct BUTTON0INFO {
- HDC hdcWindow;
- BOOL fMoved;
- DWORD dwSeqLastSeen;
- } BUTTON0INFO, *PBUTTON0INFO;
- void Scrawl_OnButton0Down_FlushMotion(PBUTTON0INFO pb0i)
- {
- if (pb0i->fMoved) {
- pb0i->fMoved = 0;
- pb0i->dwSeqLastSeen = 0;
- LineTo(pb0i->hdcWindow, g_x, g_y);
- LineTo(g_hdc, g_x, g_y);
- }
- }
- /****************************************************************************
- *
- * Scrawl_OnButton0Down
- *
- * Enter draw mode.
- *
- * If we are drawing a curve, then read buffered data and draw
- * lines from point to point. By reading buffered data, we can
- * track the motion of the mouse accurately without coalescing.
- *
- * This function illustrates how a non-message-based program can
- * process buffered data directly from a device, processing
- * messages only occasionally (as required by Windows).
- *
- * This function also illustrates how an application can piece
- * together buffered data elements based on the sequence number.
- * A single mouse action (e.g., moving diagonally) is reported
- * as a series of events, all with the same sequence number.
- * Zero is never a valid DirectInput sequence number, so it is
- * safe to use it as a sentinel value.
- *
- ****************************************************************************/
- void Scrawl_OnButton0Down(HWND hwnd)
- {
- BUTTON0INFO b0i;
- /* Hide the cursor while scrawling */
- g_fShowCursor = FALSE;
- InvalidateCursorRect(hwnd);
- UpdateWindow(hwnd);
- /*
- * For performance, draw directly onto the window's DC instead of
- * invalidating and waiting for the WM_PAINT message. Of course,
- * we always draw onto our bitmap, too, since that's what really
- * counts.
- */
- /* BUGBUG -- select a decent pen, too */
- b0i.hdcWindow = GetDC(hwnd);
- MoveToEx(b0i.hdcWindow, g_x, g_y, 0);
- MoveToEx(g_hdc, g_x, g_y, 0);
- /* BUGBUG -- save old pen */
- SelectObject(b0i.hdcWindow, GetStockObject(BLACK_PEN));
- SelectObject(g_hdc, GetStockObject(BLACK_PEN));
- b0i.fMoved = 0;
- b0i.dwSeqLastSeen = 0;
- /*
- * Keep reading data elements until we see a "mouse button up" event.
- */
- BOOL fDone = 0;
- while (!fDone) {
- DIDEVICEOBJECTDATA od;
- DWORD dwElements = 1;
- HRESULT hr = g_pMouse->GetDeviceData(
- sizeof(DIDEVICEOBJECTDATA), &od,
- &dwElements, 0);
- /* Unable to read data */
- if (FAILED(hr)) {
- break;
- }
- /*
- * If no data available, finish the element we had been
- * collecting, and then process our message queue so
- * the system don't think we're hung.
- */
- if (dwElements == 0) {
- /* If there is a partial motion, flush it out */
- Scrawl_OnButton0Down_FlushMotion(&b0i);
- MSG msg;
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- /* If it's a quit message, we're outta here */
- if (msg.message == WM_QUIT) {
- fDone = TRUE;
- /*
- * Re-post the quit message so the
- * outer loop will see it and exit.
- */
- PostQuitMessage(msg.wParam);
- break;
- } else {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- continue;
- }
- /* If this is the start of a new event, flush out the old one */
- if (od.dwSequence != b0i.dwSeqLastSeen) {
- Scrawl_OnButton0Down_FlushMotion(&b0i);
- b0i.dwSeqLastSeen = od.dwSequence;
- }
- /* Look at the element to see what happened */
- switch (od.dwOfs) {
- /* DIMOFS_X: Mouse horizontal motion */
- case DIMOFS_X:
- UpdateCursorPosition(od.dwData, 0);
- b0i.fMoved = 1;
- break;
- /* DIMOFS_Y: Mouse vertical motion */
- case DIMOFS_Y:
- UpdateCursorPosition(0, od.dwData);
- b0i.fMoved = 1;
- break;
- /* DIMOFS_BUTTON0: Button 0 pressed or released */
- case DIMOFS_BUTTON0:
- if (!(od.dwData & 0x80)) { /* Button released */
- fDone = 1;
- Scrawl_OnButton0Down_FlushMotion(&b0i); /* Flush out dregs */
- }
- break;
- }
- }
- ReleaseDC(hwnd, b0i.hdcWindow);
- /* Re-show the cursor now that scrawling is finished */
- g_fShowCursor = TRUE;
- InvalidateCursorRect(hwnd);
- }
- /****************************************************************************
- *
- * Scrawl_OnButton1Up
- *
- * Pop up a context menu.
- *
- ****************************************************************************/
- void Scrawl_OnButton1Up(HWND hwnd)
- {
- POINT pt = { g_x, g_y };
- ClientToScreen(hwnd, &pt);
- /*
- * Unacquire the devices so the user can interact with the menu.
- *
- * Put the Windows cursor at the same location as our virtual cursor.
- *
- * Hide the cursor while moving it so you don't get annoying flicker.
- */
- ShowCursor(FALSE);
- g_fActive = FALSE;
- Scrawl_SyncAcquire(hwnd);
- SetCursorPos(pt.x, pt.y);
- ShowCursor(TRUE);
- HMENU hmenuPopup = GetSystemMenu(hwnd, FALSE);
- UINT idc = TrackPopupMenuEx(hmenuPopup,
- TPM_RIGHTBUTTON | TPM_RETURNCMD,
- pt.x, pt.y, hwnd, 0);
- PostMessage(hwnd, WM_SYSCOMMAND, idc, 0L);
- }
- /****************************************************************************
- *
- * Scrawl_OnMouseInput
- *
- * The mouse moved while nothing was happening. Walk the event list
- * and update the mouse position for each event. If we see a button
- * event, then stop pulling events and leave the elements in the
- * input buffer for the drawing handler to pull.
- *
- *
- ****************************************************************************/
- void
- Scrawl_OnMouseInput(HWND hwnd)
- {
- /* Invalidate the old cursor so it will be erased */
- InvalidateCursorRect(hwnd);
- /*
- * Attempt to read one data element. Continue as long as
- * device data is available.
- */
- BOOL fDone = 0;
- while (!fDone) {
- DIDEVICEOBJECTDATA od;
- DWORD dwElements = 1;
- HRESULT hr = g_pMouse->GetDeviceData(
- sizeof(DIDEVICEOBJECTDATA), &od,
- &dwElements, 0);
- if (hr == DIERR_INPUTLOST) {
- /*
- * We had acquisition, but lost it. Try to reacquire it.
- *
- * WARNING! DO NOT ATTEMPT TO REACQUIRE IF YOU GET
- * DIERR_NOTACQUIRED! Otherwise, you're extremely likely
- * to get caught in an infinite loop: The acquire will fail,
- * and you'll get another DIERR_NOTACQUIRED so you'll
- * try to aquire again, and that'll fail, etc.
- */
- PostMessage(hwnd, WM_SYNCACQUIRE, 0, 0L);
- break;
- }
- /* Unable to read data or no data available */
- if (FAILED(hr) || dwElements == 0) {
- break;
- }
- /* Look at the element to see what happened */
- switch (od.dwOfs) {
- /* DIMOFS_X: Mouse horizontal motion */
- case DIMOFS_X: UpdateCursorPosition(od.dwData, 0); break;
- /* DIMOFS_Y: Mouse vertical motion */
- case DIMOFS_Y: UpdateCursorPosition(0, od.dwData); break;
- /* DIMOFS_BUTTON0: Button 0 pressed or released */
- case DIMOFS_BUTTON0:
- if (od.dwData & 0x80) { /* Button pressed */
- fDone = 1;
- Scrawl_OnButton0Down(hwnd); /* Go into button-down mode */
- }
- break;
- /* DIMOFS_BUTTON1: Button 1 pressed or released */
- case DIMOFS_BUTTON1:
- if (!(od.dwData & 0x80)) { /* Button released */
- fDone = 1;
- Scrawl_OnButton1Up(hwnd); /* Context menu time */
- }
- }
- }
- /* Invalidate the new cursor so it will be drawn */
- InvalidateCursorRect(hwnd);
- }
- /****************************************************************************
- *
- * ScrawlWndProc
- *
- * Application window procedure.
- *
- ****************************************************************************/
- LONG CALLBACK ScrawlWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
- {
- switch (msg) {
- HANDLE_MSG(hwnd, WM_CREATE, Scrawl_OnCreate);
- HANDLE_MSG(hwnd, WM_PAINT, Scrawl_OnPaint);
- HANDLE_MSG(hwnd, WM_INITMENUPOPUP, Scrawl_OnInitMenuPopup);
- HANDLE_MSG(hwnd, WM_KEYDOWN, Scrawl_OnKeyDown);
- /*
- * Reacquire the mouse and keyboard when we are the active window.
- * Unacquire them when we stop being the active window.
- */
- case WM_ACTIVATE:
- g_fActive = wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE;
- Scrawl_SyncAcquire(hwnd);
- break;
- /*
- * Unacquire the devices if a menu appears, so that the user can
- * interact with the menu in the normal manner.
- *
- * From Windows' point of view, we are still the active window
- * when a menu appears, but we want to act like the menu deactivated
- * us.
- */
- case WM_ENTERMENULOOP:
- case WM_ENTERSIZEMOVE:
- g_fActive = FALSE;
- Scrawl_SyncAcquire(hwnd);
- break;
- /*
- * Reacquire the devices when the menu goes away.
- *
- * SUBTLETY 1: Windows actually sends the WM_EXITMENULOOP message
- * before all the menu-related stuff is finished, so post ourselves
- * a private message to reacquire after the menu has been torn
- * down for real.
- *
- * SUBTLETY 2: Don't assume that just because the menu is going
- * away that you are still the active window. You might not be.
- *
- * SUBTLETY 3: Don't assume that just because you're the active
- * window that you are restored and ready for action. You might
- * just be a taskbar button.
- */
- case WM_EXITMENULOOP:
- case WM_EXITSIZEMOVE:
- g_fActive = GetActiveWindow() == hwnd && !IsIconic(hwnd);
- PostMessage(hwnd, WM_SYNCACQUIRE, 0, 0L);
- break;
- case WM_SYNCACQUIRE:
- Scrawl_SyncAcquire(hwnd);
- break;
- case WM_SYSCOMMAND:
- LRESULT lRc;
- switch (GET_WM_COMMAND_ID(wParam, lParam)) {
- case IDC_CLEAR:
- Scrawl_OnClear(hwnd);
- lRc = 0;
- break;
- case IDC_ABOUT:
- MessageBox(hwnd, "Scrawl DirectInput Sample v1.0",
- c_szAppName, MB_OK);
- lRc = 0;
- break;
- /*
- * Eat the screen-saver notification.
- */
- case SC_SCREENSAVE:
- lRc = 0;
- break;
- case IDC_SENSITIVITY_LOW:
- case IDC_SENSITIVITY_NORMAL:
- case IDC_SENSITIVITY_HIGH:
- g_iSensitivity = (signed short)GET_WM_COMMAND_ID(wParam, lParam)
- - IDC_SENSITIVITY_NORMAL;
- lRc = 0;
- break;
- default:
- lRc = DefWindowProc(hwnd, msg, wParam, lParam);
- break;
- }
- /*
- * The WM_SYSCOMMAND might've been a WM_CLOSE, in which case
- * our window no longer exists. So be careful.
- */
- if (IsWindow(hwnd)) {
- Scrawl_SyncAcquire(hwnd);
- }
- return lRc;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- }
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
- /****************************************************************************
- *
- * AppInit
- *
- * Set up everything the application needs to get started.
- *
- ****************************************************************************/
- HWND AppInit(HINSTANCE hinst, int nCmdShow)
- {
- /* Save instance handle for people who care */
- g_hinst = hinst;
- /*
- * Get our crosshairs cursor and extract the the width and
- * hotspot location so we can draw it manually.
- */
- g_hcurCross = LoadCursor(NULL, IDC_CROSS);
- ICONINFO ii;
- GetIconInfo(g_hcurCross, &ii);
- BITMAP bm;
- GetObject(ii.hbmMask, sizeof(BITMAP), &bm);
- if (ii.hbmMask) DeleteObject(ii.hbmMask);
- if (ii.hbmColor) DeleteObject(ii.hbmColor);
- g_dxCrossHot = ii.xHotspot;
- g_dyCrossHot = ii.yHotspot;
- g_cxCross = bm.bmWidth;
- g_cyCross = bm.bmHeight;
- /*
- * Create our scrawl bitmap and set it up.
- */
- HDC hdc = GetDC(0);
- g_hdc = CreateCompatibleDC(hdc);
- ReleaseDC(0, hdc);
- if (!g_hdc) return NULL;
- g_hbm = CreateBitmap(DINPUT_CXBITMAP, DINPUT_CYBITMAP, 1, 1, 0);
- if (!g_hbm) return NULL;
- g_hbmDeselect = (HBITMAP) SelectObject(g_hdc, g_hbm);
- Scrawl_OnClear(0);
- /*
- * Set up the window class.
- */
- WNDCLASS wc;
- wc.hCursor = LoadCursor(0, IDC_ARROW);
- wc.hIcon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_MAIN));
- wc.lpszMenuName = NULL;
- wc.lpszClassName = c_szAppName;
- wc.hbrBackground = 0;
- wc.hInstance = hinst;
- wc.style = 0;
- wc.lpfnWndProc = ScrawlWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- if (!RegisterClass(&wc)) {
- return NULL;
- }
- DWORD dwStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
- DWORD dwExStyle = WS_EX_APPWINDOW;
- RECT rc = { 0, 0, DINPUT_CXBITMAP, DINPUT_CYBITMAP };
- AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle);
- HWND hwnd = CreateWindowEx(
- dwExStyle, // ExStyle
- c_szAppName, // Class name
- c_szAppName, // Caption
- dwStyle, // Style
- CW_USEDEFAULT, CW_USEDEFAULT, // Position
- rc.right - rc.left, // cx
- rc.bottom - rc.top, // cy
- 0, // Parent window (no parent)
- 0, // use class menu
- g_hinst, // handle to module instance
- 0 // no params to pass on
- );
- if (!DIInit(hwnd)) {
- DestroyWindow(hwnd);
- return NULL;
- }
- ShowWindow(hwnd, nCmdShow);
- return hwnd;
- }
- /****************************************************************************
- *
- * WinMain
- *
- * Application entry point.
- *
- * The main message loop illustrates how a message-driven program
- * can use event notifications to be signalled when new data is
- * available from a device.
- *
- ****************************************************************************/
- int PASCAL
- WinMain(HINSTANCE hinst, HINSTANCE hinstPrev, LPSTR szCmdLine, int nCmdShow)
- {
- MSG msg;
- msg.wParam = 0; /* In case something goes horribly wrong */
- HWND hwnd = AppInit(hinst, nCmdShow);
- if (hwnd) {
- /*
- * Since we use notification handles, we need to use
- * MsgWaitForMultipleObjects to wait for the event or
- * a message, whichever comes first.
- */
- BOOL fDone = FALSE;
- while (!fDone) {
- DWORD dw = MsgWaitForMultipleObjects(1, &g_hevtMouse, 0, INFINITE,
- QS_ALLINPUT);
- switch (dw) {
- /* WAIT_OBJECT_0 + 0 means that g_hevtMouse was signalled */
- case WAIT_OBJECT_0 + 0:
- Scrawl_OnMouseInput(hwnd);
- break;
- /* WAIT_OBJECT_0 + 1 means that we have messages to process */
- case WAIT_OBJECT_0 + 1:
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- /* If it's a quit message, we're outta here */
- if (msg.message == WM_QUIT) {
- fDone = TRUE;
- } else {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- break;
- }
- }
- }
- DITerm();
- if (g_hdc) {
- if (g_hbmDeselect) {
- SelectObject(g_hdc, g_hbmDeselect);
- }
- DeleteDC(g_hdc);
- }
- if (g_hbm) {
- DeleteObject(g_hbm);
- }
- return msg.wParam;
- }