Example #1
0
static LRESULT myWindowProc(HWND hWnd,	UINT Msg, WPARAM wParam, LPARAM lParam)
{
	HDC			dc;
	PAINTSTRUCT	ps;
	#if GINPUT_NEED_TOGGLE
		HBRUSH		hbrOn, hbrOff;
		HPEN		pen;
		RECT		rect;
		HGDIOBJ		old;
		POINT 		p;
		coord_t		pos;
		uint8_t		bit;
	#endif

	switch (Msg) {
	case WM_CREATE:
		break;
	case WM_LBUTTONDOWN:
		#if GINPUT_NEED_MOUSE
			if ((coord_t)HIWORD(lParam) < wHeight) {
				mousebuttons |= GINPUT_MOUSE_BTN_LEFT;
				goto mousemove;
			}
		#endif
		#if GINPUT_NEED_TOGGLE
			bit = 1 << ((coord_t)LOWORD(lParam)*8/wWidth);
			toggles ^= bit;
			rect.left = 0;
			rect.right = wWidth;
			rect.top = wHeight;
			rect.bottom = wHeight + WIN32_BUTTON_AREA;
			InvalidateRect(hWnd, &rect, FALSE);
			UpdateWindow(hWnd);
			#if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
				ginputToggleWakeup();
			#endif
		#endif
		break;
	case WM_LBUTTONUP:
		#if GINPUT_NEED_TOGGLE
			if ((toggles & 0xF0)) {
				toggles &= 0x0F;
				rect.left = 0;
				rect.right = wWidth;
				rect.top = wHeight;
				rect.bottom = wHeight + WIN32_BUTTON_AREA;
				InvalidateRect(hWnd, &rect, FALSE);
				UpdateWindow(hWnd);
				#if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
					ginputToggleWakeup();
				#endif
			}
		#endif
		#if GINPUT_NEED_MOUSE
			if ((coord_t)HIWORD(lParam) < wHeight) {
				mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT;
				goto mousemove;
			}
		#endif
		break;
#if GINPUT_NEED_MOUSE
	case WM_MBUTTONDOWN:
		if ((coord_t)HIWORD(lParam) < wHeight) {
			mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE;
			goto mousemove;
		}
		break;
	case WM_MBUTTONUP:
		if ((coord_t)HIWORD(lParam) < wHeight) {
			mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE;
			goto mousemove;
		}
		break;
	case WM_RBUTTONDOWN:
		if ((coord_t)HIWORD(lParam) < wHeight) {
			mousebuttons |= GINPUT_MOUSE_BTN_RIGHT;
			goto mousemove;
		}
		break;
	case WM_RBUTTONUP:
		if ((coord_t)HIWORD(lParam) < wHeight) {
			mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT;
			goto mousemove;
		}
		break;
	case WM_MOUSEMOVE:
		if ((coord_t)HIWORD(lParam) >= wHeight)
			break;
	mousemove:
		mousex = (coord_t)LOWORD(lParam); 
		mousey = (coord_t)HIWORD(lParam); 
		#if GINPUT_MOUSE_POLL_PERIOD == TIME_INFINITE
			ginputMouseWakeup();
		#endif
		break;
#endif
	case WM_SYSKEYDOWN:
	case WM_KEYDOWN:
	case WM_SYSKEYUP:
	case WM_KEYUP:
		break;
	case WM_CHAR:
	case WM_DEADCHAR:
	case WM_SYSCHAR:
	case WM_SYSDEADCHAR:
		break;
	case WM_PAINT:
		dc = BeginPaint(hWnd, &ps);
		BitBlt(dc, ps.rcPaint.left, ps.rcPaint.top,
			ps.rcPaint.right - ps.rcPaint.left,
			(ps.rcPaint.bottom > wHeight ? wHeight : ps.rcPaint.bottom) - ps.rcPaint.top,
			dcBuffer, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);
		#if GINPUT_NEED_TOGGLE
			if (ps.rcPaint.bottom >= wHeight) {
				pen = CreatePen(PS_SOLID, 1, COLOR2BGR(Black));
				hbrOn = CreateSolidBrush(COLOR2BGR(Blue));
				hbrOff = CreateSolidBrush(COLOR2BGR(Gray));
				old = SelectObject(dc, pen);
				MoveToEx(dc, 0, wHeight, &p);
				LineTo(dc, wWidth, wHeight);
				for(pos = 0, bit=1; pos < wWidth; pos=rect.right, bit <<= 1) {
					rect.left = pos;
					rect.right = pos + wWidth/8;
					rect.top = wHeight;
					rect.bottom = wHeight + WIN32_BUTTON_AREA;
					FillRect(dc, &rect, (toggles & bit) ? hbrOn : hbrOff);
					if (pos > 0) {
						MoveToEx(dc, rect.left, rect.top, &p);
						LineTo(dc, rect.left, rect.bottom);
					}
				}
				DeleteObject(hbrOn);
				DeleteObject(hbrOff);
				SelectObject(dc, old);
			}
		#endif
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		SelectObject(dcBuffer, dcOldBitmap);
		DeleteDC(dcBuffer);
		DeleteObject(dcBitmap);
		winRootWindow = NULL;
		break;
	default:
		return DefWindowProc(hWnd, Msg, wParam, lParam);
	}
	return 0;
}
static LRESULT myWindowProc(HWND hWnd,	UINT Msg, WPARAM wParam, LPARAM lParam)
{
	HDC				dc;
	PAINTSTRUCT		ps;
	GDisplay *		g;
	winPriv *		priv;
	#if GINPUT_NEED_TOGGLE
		HBRUSH		hbrOn, hbrOff;
		HPEN		pen;
		RECT		rect;
		HGDIOBJ		old;
		POINT 		p;
		coord_t		pos;
		uint8_t		bit;
	#endif

	switch (Msg) {
	case WM_CREATE:
		// Get our GDisplay structure and attach it to the window
		g = (GDisplay *)((LPCREATESTRUCT)lParam)->lpCreateParams;
		priv = (winPriv *)g->priv;
		SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)g);

		// Fill in the private area
		priv->hwnd = hWnd;
		dc = GetDC(hWnd);
		priv->dcBitmap = CreateCompatibleBitmap(dc, g->g.Width, g->g.Height);
		priv->dcBuffer = CreateCompatibleDC(dc);
		ReleaseDC(hWnd, dc);
		priv->dcOldBitmap = SelectObject(priv->dcBuffer, priv->dcBitmap);

		// Mark the window as ready to go
		g->flags |= GDISP_FLG_READY;
		break;

	#if GINPUT_NEED_MOUSE || GINPUT_NEED_TOGGLE
		case WM_LBUTTONDOWN:
			// Get our GDisplay structure
			g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
			priv = (winPriv *)g->priv;

			// Handle mouse down on the window
			#if GINPUT_NEED_MOUSE
				if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
					priv->mousebuttons |= GINPUT_MOUSE_BTN_LEFT;
					goto mousemove;
				}
			#endif

			// Handle mouse down on the toggle area
			#if GINPUT_NEED_TOGGLE
				if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASTOGGLE)) {
					bit = 1 << ((coord_t)LOWORD(lParam)*8/g->g.Width);
					priv->toggles ^= bit;
					rect.left = 0;
					rect.right = GDISP_SCREEN_WIDTH;
					rect.top = GDISP_SCREEN_HEIGHT;
					rect.bottom = GDISP_SCREEN_HEIGHT + WIN32_BUTTON_AREA;
					InvalidateRect(hWnd, &rect, FALSE);
					UpdateWindow(hWnd);
					#if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
						ginputToggleWakeup();
					#endif
				}
			#endif
			break;

		case WM_LBUTTONUP:
			// Get our GDisplay structure
			g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
			priv = (winPriv *)g->priv;

			// Handle mouse up on the toggle area
			#if GINPUT_NEED_TOGGLE
				if ((g->flags & GDISP_FLG_HASTOGGLE)) {
					if ((priv->toggles & 0x0F)) {
						priv->toggles &= ~0x0F;
						rect.left = 0;
						rect.right = GDISP_SCREEN_WIDTH;
						rect.top = GDISP_SCREEN_HEIGHT;
						rect.bottom = GDISP_SCREEN_HEIGHT + WIN32_BUTTON_AREA;
						InvalidateRect(hWnd, &rect, FALSE);
						UpdateWindow(hWnd);
						#if GINPUT_TOGGLE_POLL_PERIOD == TIME_INFINITE
							ginputToggleWakeup();
						#endif
					}
				}
			#endif

			// Handle mouse up on the window
			#if GINPUT_NEED_MOUSE
				if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
					priv->mousebuttons &= ~GINPUT_MOUSE_BTN_LEFT;
					goto mousemove;
				}
			#endif
			break;
	#endif

	#if GINPUT_NEED_MOUSE
		case WM_MBUTTONDOWN:
			g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
			priv = (winPriv *)g->priv;
			if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
				priv->mousebuttons |= GINPUT_MOUSE_BTN_MIDDLE;
				goto mousemove;
			}
			break;
		case WM_MBUTTONUP:
			g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
			priv = (winPriv *)g->priv;
			if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
				priv->mousebuttons &= ~GINPUT_MOUSE_BTN_MIDDLE;
				goto mousemove;
			}
			break;
		case WM_RBUTTONDOWN:
			g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
			priv = (winPriv *)g->priv;
			if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
				priv->mousebuttons |= GINPUT_MOUSE_BTN_RIGHT;
				goto mousemove;
			}
			break;
		case WM_RBUTTONUP:
			g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
			priv = (winPriv *)g->priv;
			if ((coord_t)HIWORD(lParam) < GDISP_SCREEN_HEIGHT) {
				priv->mousebuttons &= ~GINPUT_MOUSE_BTN_RIGHT;
				goto mousemove;
			}
			break;
		case WM_MOUSEMOVE:
			g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
			priv = (winPriv *)g->priv;
			if ((coord_t)HIWORD(lParam) >= GDISP_SCREEN_HEIGHT)
				break;
		mousemove:
			priv->mousex = (coord_t)LOWORD(lParam);
			priv->mousey = (coord_t)HIWORD(lParam);
			if ((gmvmt(priv->mouse)->d.flags & GMOUSE_VFLG_NOPOLL))		// For normal setup this is always TRUE
				_gmouseWakeup(priv->mouse);
			break;
	#endif

	case WM_SYSKEYDOWN:
	case WM_KEYDOWN:
	case WM_SYSKEYUP:
	case WM_KEYUP:
		break;
	case WM_CHAR:
	case WM_DEADCHAR:
	case WM_SYSCHAR:
	case WM_SYSDEADCHAR:
		break;

	case WM_ERASEBKGND:
		// Pretend we have erased the background.
		// We know we don't really need to do this as we
		// redraw the entire surface in the WM_PAINT handler.
		return TRUE;

	case WM_PAINT:
		// Get our GDisplay structure
		g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
		priv = (winPriv *)g->priv;

		// Paint the main window area
		WaitForSingleObject(drawMutex, INFINITE);
		dc = BeginPaint(hWnd, &ps);
		BitBlt(dc, ps.rcPaint.left, ps.rcPaint.top,
			ps.rcPaint.right - ps.rcPaint.left,
			(ps.rcPaint.bottom > GDISP_SCREEN_HEIGHT ? GDISP_SCREEN_HEIGHT : ps.rcPaint.bottom) - ps.rcPaint.top,
			priv->dcBuffer, ps.rcPaint.left, ps.rcPaint.top, SRCCOPY);

		// Paint the toggle area
		#if GINPUT_NEED_TOGGLE
			if (ps.rcPaint.bottom >= GDISP_SCREEN_HEIGHT && (g->flags & GDISP_FLG_HASTOGGLE)) {
				pen = CreatePen(PS_SOLID, 1, gdispColor2Native(Black));
				hbrOn = CreateSolidBrush(gdispColor2Native(Blue));
				hbrOff = CreateSolidBrush(gdispColor2Native(Gray));
				old = SelectObject(dc, pen);
				MoveToEx(dc, 0, GDISP_SCREEN_HEIGHT, &p);
				LineTo(dc, GDISP_SCREEN_WIDTH, GDISP_SCREEN_HEIGHT);
				for(pos = 0, bit=1; pos < wWidth; pos=rect.right, bit <<= 1) {
					rect.left = pos;
					rect.right = pos + GDISP_SCREEN_WIDTH/8;
					rect.top = GDISP_SCREEN_HEIGHT;
					rect.bottom = GDISP_SCREEN_HEIGHT + WIN32_BUTTON_AREA;
					FillRect(dc, &rect, (priv->toggles & bit) ? hbrOn : hbrOff);
					if (pos > 0) {
						MoveToEx(dc, rect.left, rect.top, &p);
						LineTo(dc, rect.left, rect.bottom);
					}
				}
				DeleteObject(hbrOn);
				DeleteObject(hbrOff);
				SelectObject(dc, old);
			}
		#endif
		EndPaint(hWnd, &ps);
		ReleaseMutex(drawMutex);
		break;

	case WM_DESTROY:
		// Get our GDisplay structure
		g = (GDisplay *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
		priv = (winPriv *)g->priv;

		// Restore the window and free our bitmaps
		SelectObject(priv->dcBuffer, priv->dcOldBitmap);
		DeleteDC(priv->dcBuffer);
		DeleteObject(priv->dcBitmap);

		// Cleanup the private area
		gfxFree(priv);

		// Quit the application
		PostQuitMessage(0);

		// Actually the above doesn't work (who knows why)
		ExitProcess(0);
		break;

	default:
		return DefWindowProc(hWnd, Msg, wParam, lParam);
	}
	return 0;
}