Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

433 lines
12 KiB

/****************************** Module Header ******************************\
* Module Name: reader.c
*
* Copyright (c) 1985 - 1999, Microsoft Corporation
*
* Implements support reader-mode routines for auto-scrolling and panning.
*
* History:
* 31-Jan-1997 vadimg created
\***************************************************************************/
#include "precomp.h"
#pragma hdrstop
#define TIMERID 1
__inline FReader2Dim(PREADERINFO prdr)
{
return ((prdr->dwFlags & (RDRMODE_HORZ | RDRMODE_VERT)) ==
(RDRMODE_HORZ | RDRMODE_VERT));
}
__inline FReaderVert(PREADERINFO prdr)
{
return (prdr->dwFlags & RDRMODE_VERT);
}
__inline FReaderHorz(PREADERINFO prdr)
{
return (prdr->dwFlags & RDRMODE_HORZ);
}
__inline FReaderDiag(PREADERINFO prdr)
{
return (prdr->dwFlags & RDRMODE_DIAG);
}
/***************************************************************************\
* ReaderSetCursor
*
\***************************************************************************/
void ReaderSetCursor(PREADERINFO prdr, UINT uCursor)
{
if (prdr->uCursor != uCursor) {
NtUserSetCursor(LoadCursor(NULL, MAKEINTRESOURCE(uCursor)));
prdr->uCursor = uCursor;
}
}
/***************************************************************************\
* ReaderMouseMove
*
* Calculate dx and dy based on the flags passed in. Provide visual
* feedback for the reader mode by setting the correct cursor.
*
* 2-Feb-1997 vadimg created
\***************************************************************************/
void ReaderMouseMove(PWND pwnd, PREADERINFO prdr, LPARAM lParam)
{
int dx = 0, dy = 0;
LPRECT prc = KPRECT_TO_PRECT(&pwnd->rcWindow);
UINT uCursor;
POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
_ClientToScreen(pwnd, &pt);
if (FReaderVert(prdr)) {
if (pt.y < prc->top) {
dy = pt.y - prc->top;
} else if (pt.y > prc->bottom) {
dy = pt.y - prc->bottom;
}
}
if (FReaderHorz(prdr)) {
if (pt.x < prc->left) {
dx = pt.x - prc->left;
} else if (pt.x > prc->right) {
dx = pt.x - prc->right;
}
}
if (FReader2Dim(prdr)) {
if (dx == 0 && dy == 0) {
ReaderSetCursor(prdr, OCR_RDR2DIM);
goto Exit;
}
if (!FReaderDiag(prdr)) {
if (prdr->dy != 0) {
if (abs(dx) > abs(prdr->dy)) {
dy = 0;
} else {
dx = 0;
}
} else if (prdr->dx != 0) {
if (abs(dy) > abs(prdr->dx)) {
dx = 0;
} else {
dy = 0;
}
} else if (dy != 0) {
dx = 0;
}
}
} else if (FReaderVert(prdr) && dy == 0) {
ReaderSetCursor(prdr, OCR_RDRVERT);
goto Exit;
} else if (FReaderHorz(prdr) && dx == 0) {
ReaderSetCursor(prdr, OCR_RDRHORZ);
goto Exit;
}
if (dx == 0) {
uCursor = (dy > 0) ? OCR_RDRSOUTH : OCR_RDRNORTH;
} else if (dx > 0) {
if (dy == 0) {
uCursor = OCR_RDREAST;
} else {
uCursor = (dy > 0) ? OCR_RDRSOUTHEAST : OCR_RDRNORTHEAST;
}
} else if (dx < 0) {
if (dy == 0) {
uCursor = OCR_RDRWEST;
} else {
uCursor = (dy > 0) ? OCR_RDRSOUTHWEST : OCR_RDRNORTHWEST;
}
}
ReaderSetCursor(prdr, uCursor);
Exit:
prdr->dx = dx;
prdr->dy = dy;
}
/***************************************************************************\
* ReaderFeedback
*
* 2-Feb-1997 vadimg created
\***************************************************************************/
void ReaderFeedback(PWND pwnd, PREADERINFO prdr)
{
if (prdr->dx == 0 && prdr->dy == 0)
return;
if (prdr->pfnReaderModeProc(prdr->lParam, RDRCODE_SCROLL,
prdr->dx, prdr->dy) == 0) {
NtUserDestroyWindow(PtoH(pwnd));
}
}
/***************************************************************************\
* ReaderWndProc
*
* 31-Jan-1997 vadimg created
\***************************************************************************/
LRESULT CALLBACK ReaderWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HDC hdc, hdcMem;
HPEN hpen, hpenOld;
HBRUSH hbrOld;
HRGN hrgn;
RECT rc;
POINT pt;
int nBitmap, cx, cy;
PREADERINFO prdr;
PWND pwnd;
LPCREATESTRUCT pcs;
PREADERMODE prdrm;
BITMAP bmp;
if ((pwnd = ValidateHwnd(hwnd)) == NULL)
return 0;
prdr = ((PREADERWND)pwnd)->prdr;
switch (msg) {
case WM_TIMER:
ReaderFeedback(pwnd, prdr);
return 0;
case WM_MOUSEWHEEL:
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_XBUTTONUP:
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_XBUTTONDOWN:
case WM_KEYDOWN:
ReleaseCapture();
return 0;
case WM_MOUSEMOVE:
ReaderMouseMove(pwnd, prdr, lParam);
return 0;
case WM_MBUTTONUP:
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
GetClientRect(hwnd, &rc);
if (!PtInRect(&rc, pt)) {
ReleaseCapture();
}
return 0;
case WM_CAPTURECHANGED:
NtUserDestroyWindow(hwnd);
return 0;
case WM_NCDESTROY:
NtUserKillTimer(hwnd, TIMERID);
prdr->pfnReaderModeProc(prdr->lParam, RDRCODE_END, 0, 0);
if (prdr->hbm != NULL) {
DeleteObject(prdr->hbm);
}
UserLocalFree(prdr);
return 0;
case WM_CREATE:
if ((prdr = UserLocalAlloc(HEAP_ZERO_MEMORY, sizeof(READERINFO))) == NULL)
return -1;
pcs = (LPCREATESTRUCT)lParam;
prdrm = (PREADERMODE)pcs->lpCreateParams;
RtlCopyMemory(prdr, prdrm, sizeof(READERMODE));
SetWindowLongPtr(hwnd, 0, (LONG_PTR)prdr);
if (prdr->pfnReaderModeProc == NULL) {
return -1;
}
if (FReader2Dim(prdr)) {
nBitmap = OBM_RDR2DIM;
} else if (FReaderVert(prdr)) {
nBitmap = OBM_RDRVERT;
} else if (FReaderHorz(prdr)) {
nBitmap = OBM_RDRHORZ;
} else {
return -1;
}
SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_CLIPSIBLINGS);
prdr->hbm = LoadBitmap(hmodUser, MAKEINTRESOURCE(nBitmap));
if (prdr->hbm == NULL ||
GetObject(prdr->hbm, sizeof(BITMAP), &bmp) == 0) {
return -1;
}
if (prdr->pfnReaderModeProc(prdr->lParam, RDRCODE_START, 0, 0) == 0) {
return -1;
}
prdr->dxBmp = bmp.bmWidth;
prdr->dyBmp = bmp.bmHeight;
cx = bmp.bmWidth + 1;
cy = bmp.bmHeight + 1;
GetCursorPos(&pt);
pt.x -= cx/2;
pt.y -= cy/2;
if ((hrgn = CreateEllipticRgn(0, 0, cx, cy)) != NULL) {
SetWindowRgn(hwnd, hrgn, FALSE);
}
NtUserSetWindowPos(hwnd, HWND_TOPMOST, pt.x, pt.y, cx, cy,
SWP_SHOWWINDOW | SWP_NOACTIVATE);
NtUserSetCapture(hwnd);
NtUserSetFocus(hwnd);
NtUserSetTimer(hwnd, TIMERID, 10, NULL);
return 0;
case WM_ERASEBKGND:
hdc = (HDC)wParam;
if ((hdcMem = CreateCompatibleDC(hdc)) == NULL)
return FALSE;
SelectObject(hdcMem, prdr->hbm);
hpen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
hpenOld = (HPEN)SelectObject(hdc, hpen);
hbrOld = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH));
BitBlt(hdc, 0, 0, prdr->dxBmp, prdr->dyBmp, hdcMem, 0, 0, SRCCOPY);
Ellipse(hdc, 0, 0, prdr->dxBmp, prdr->dyBmp);
SelectObject(hdc, hpenOld);
SelectObject(hdc, hbrOld);
DeleteObject(hpen);
DeleteObject(hdcMem);
return TRUE;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
/***************************************************************************\
* ReaderProcInternal
*
\***************************************************************************/
LONG ReaderProcInternal(LPARAM lParam, int nCode, int dx, int dy)
{
DWORD dwDelay;
UINT uMsg, uCode;
int n, nAbs;
if (nCode != RDRCODE_SCROLL)
return TRUE;
if (dy != 0) {
uCode = SB_LINEUP;
uMsg = WM_VSCROLL;
n = dy;
} else {
uCode = SB_LINELEFT;
uMsg = WM_HSCROLL;
n = dx;
}
nAbs = abs(n);
if (nAbs >= 120) {
uCode += 2;
dwDelay = 0;
} else {
dwDelay = 1000 - (nAbs / 2) * 15;
}
if (n > 0) {
uCode += 1;
}
SendMessage((HWND)lParam, uMsg, MAKELONG(uCode, dwDelay), 0);
UpdateWindow((HWND)lParam);
return TRUE;
}
/***************************************************************************\
* EnterReaderMode
*
\***************************************************************************/
#define READERCLASS L"User32_ReaderMode"
ATOM gatomReaderMode = 0;
BOOL EnterReaderMode(PREADERMODE prdrm)
{
WNDCLASSEX wce;
if (GetCapture() != NULL)
return FALSE;
if (gatomReaderMode == 0) {
wce.cbSize = sizeof(wce);
wce.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
wce.lpfnWndProc = ReaderWndProc;
wce.cbClsExtra = 0;
wce.cbWndExtra = sizeof(PREADERINFO);
wce.hInstance = hmodUser;
wce.hIcon = NULL;
wce.hCursor = LoadCursor(NULL, IDC_ARROW);
wce.hbrBackground = GetStockObject(WHITE_BRUSH);
wce.lpszMenuName = NULL;
wce.lpszClassName = READERCLASS;
wce.hIconSm = NULL;
if ((gatomReaderMode = RegisterClassExWOWW(&wce, NULL, FNID_DDE_BIT, 0)) == 0) {
RIPMSG0(RIP_WARNING, "EnterReaderMode: failed to register ReaderMode");
return 0;
}
}
return (_CreateWindowEx(0, READERCLASS, NULL, 0, 0, 0, 0, 0,
NULL, NULL, hmodUser, (PVOID)prdrm, 0) != NULL);
}
/***************************************************************************\
* FScrollEnabled
*
\***************************************************************************/
BOOL FScrollEnabled(PWND pwnd, BOOL fVert)
{
PSBINFO pw;
int nFlags;
if (!TestWF(pwnd, fVert ? WFVPRESENT : WFHPRESENT))
return FALSE;
if ((pw = (PSBINFO)REBASEALWAYS(pwnd, pSBInfo)) == NULL)
return FALSE;
nFlags = fVert ? (pw->WSBflags >> 2) : pw->WSBflags;
if ((nFlags & SB_DISABLE_MASK) == SB_DISABLE_MASK)
return FALSE;
return TRUE;
}
/***************************************************************************\
* EnterReaderModeHelper
*
\***************************************************************************/
BOOL EnterReaderModeHelper(HWND hwnd)
{
PWND pwnd = ValidateHwnd(hwnd);
READERMODE rdrm;
rdrm.cbSize = sizeof(READERMODE);
rdrm.pfnReaderModeProc = ReaderProcInternal;
rdrm.lParam = (LPARAM)hwnd;
rdrm.dwFlags = 0;
if (FScrollEnabled(pwnd, TRUE)) {
rdrm.dwFlags |= RDRMODE_VERT;
}
if (FScrollEnabled(pwnd, FALSE)) {
rdrm.dwFlags |= RDRMODE_HORZ;
}
return EnterReaderMode(&rdrm);
}