Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

reader.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: reader.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * Implements support reader-mode routines for auto-scrolling and panning. 00007 * 00008 * History: 00009 * 31-Jan-1997 vadimg created 00010 \***************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 #define TIMERID 1 00016 00017 __inline FReader2Dim(PREADERINFO prdr) 00018 { 00019 return ((prdr->dwFlags & (RDRMODE_HORZ | RDRMODE_VERT)) == 00020 (RDRMODE_HORZ | RDRMODE_VERT)); 00021 } 00022 __inline FReaderVert(PREADERINFO prdr) 00023 { 00024 return (prdr->dwFlags & RDRMODE_VERT); 00025 } 00026 __inline FReaderHorz(PREADERINFO prdr) 00027 { 00028 return (prdr->dwFlags & RDRMODE_HORZ); 00029 } 00030 __inline FReaderDiag(PREADERINFO prdr) 00031 { 00032 return (prdr->dwFlags & RDRMODE_DIAG); 00033 } 00034 00035 /***************************************************************************\ 00036 * ReaderSetCursor 00037 * 00038 \***************************************************************************/ 00039 00040 void ReaderSetCursor(PREADERINFO prdr, UINT uCursor) 00041 { 00042 if (prdr->uCursor != uCursor) { 00043 NtUserSetCursor(LoadCursor(NULL, MAKEINTRESOURCE(uCursor))); 00044 prdr->uCursor = uCursor; 00045 } 00046 } 00047 00048 /***************************************************************************\ 00049 * ReaderMouseMove 00050 * 00051 * Calculate dx and dy based on the flags passed in. Provide visual 00052 * feedback for the reader mode by setting the correct cursor. 00053 * 00054 * 2-Feb-1997 vadimg created 00055 \***************************************************************************/ 00056 00057 void ReaderMouseMove(PWND pwnd, PREADERINFO prdr, LPARAM lParam) 00058 { 00059 int dx = 0, dy = 0; 00060 LPRECT prc = &pwnd->rcWindow; 00061 UINT uCursor; 00062 POINT pt = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; 00063 00064 _ClientToScreen(pwnd, &pt); 00065 00066 if (FReaderVert(prdr)) { 00067 if (pt.y < prc->top) { 00068 dy = pt.y - prc->top; 00069 } else if (pt.y > prc->bottom) { 00070 dy = pt.y - prc->bottom; 00071 } 00072 } 00073 00074 if (FReaderHorz(prdr)) { 00075 if (pt.x < prc->left) { 00076 dx = pt.x - prc->left; 00077 } else if (pt.x > prc->right) { 00078 dx = pt.x - prc->right; 00079 } 00080 } 00081 00082 if (FReader2Dim(prdr)) { 00083 if (dx == 0 && dy == 0) { 00084 ReaderSetCursor(prdr, OCR_RDR2DIM); 00085 goto Exit; 00086 } 00087 if (!FReaderDiag(prdr)) { 00088 if (prdr->dy != 0) { 00089 if (abs(dx) > abs(prdr->dy)) { 00090 dy = 0; 00091 } else { 00092 dx = 0; 00093 } 00094 } else if (prdr->dx != 0) { 00095 if (abs(dy) > abs(prdr->dx)) { 00096 dx = 0; 00097 } else { 00098 dy = 0; 00099 } 00100 } else if (dy != 0) { 00101 dx = 0; 00102 } 00103 } 00104 } else if (FReaderVert(prdr) && dy == 0) { 00105 ReaderSetCursor(prdr, OCR_RDRVERT); 00106 goto Exit; 00107 } else if (FReaderHorz(prdr) && dx == 0) { 00108 ReaderSetCursor(prdr, OCR_RDRHORZ); 00109 goto Exit; 00110 } 00111 00112 if (dx == 0) { 00113 uCursor = (dy > 0) ? OCR_RDRSOUTH : OCR_RDRNORTH; 00114 } else if (dx > 0) { 00115 if (dy == 0) { 00116 uCursor = OCR_RDREAST; 00117 } else { 00118 uCursor = (dy > 0) ? OCR_RDRSOUTHEAST : OCR_RDRNORTHEAST; 00119 } 00120 } else if (dx < 0) { 00121 if (dy == 0) { 00122 uCursor = OCR_RDRWEST; 00123 } else { 00124 uCursor = (dy > 0) ? OCR_RDRSOUTHWEST : OCR_RDRNORTHWEST; 00125 } 00126 } 00127 00128 ReaderSetCursor(prdr, uCursor); 00129 00130 Exit: 00131 prdr->dx = dx; 00132 prdr->dy = dy; 00133 } 00134 00135 /***************************************************************************\ 00136 * ReaderFeedback 00137 * 00138 * 2-Feb-1997 vadimg created 00139 \***************************************************************************/ 00140 00141 void ReaderFeedback(PWND pwnd, PREADERINFO prdr) 00142 { 00143 if (prdr->dx == 0 && prdr->dy == 0) 00144 return; 00145 00146 if (prdr->pfnReaderModeProc(prdr->lParam, RDRCODE_SCROLL, 00147 prdr->dx, prdr->dy) == 0) { 00148 NtUserDestroyWindow(PtoH(pwnd)); 00149 } 00150 } 00151 00152 /***************************************************************************\ 00153 * ReaderWndProc 00154 * 00155 * 31-Jan-1997 vadimg created 00156 \***************************************************************************/ 00157 00158 LRESULT CALLBACK ReaderWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 00159 { 00160 HDC hdc, hdcMem; 00161 HPEN hpen, hpenOld; 00162 HBRUSH hbrOld; 00163 HRGN hrgn; 00164 RECT rc; 00165 POINT pt; 00166 int nBitmap, cx, cy; 00167 PREADERINFO prdr; 00168 PWND pwnd; 00169 LPCREATESTRUCT pcs; 00170 PREADERMODE prdrm; 00171 BITMAP bmp; 00172 00173 if ((pwnd = ValidateHwnd(hwnd)) == NULL) 00174 return 0; 00175 00176 prdr = ((PREADERWND)pwnd)->prdr; 00177 00178 switch (msg) { 00179 case WM_TIMER: 00180 ReaderFeedback(pwnd, prdr); 00181 return 0; 00182 00183 case WM_MOUSEWHEEL: 00184 case WM_LBUTTONUP: 00185 case WM_RBUTTONUP: 00186 case WM_XBUTTONUP: 00187 case WM_LBUTTONDOWN: 00188 case WM_RBUTTONDOWN: 00189 case WM_MBUTTONDOWN: 00190 case WM_XBUTTONDOWN: 00191 case WM_KEYDOWN: 00192 ReleaseCapture(); 00193 return 0; 00194 00195 case WM_MOUSEMOVE: 00196 ReaderMouseMove(pwnd, prdr, lParam); 00197 return 0; 00198 00199 case WM_MBUTTONUP: 00200 pt.x = GET_X_LPARAM(lParam); 00201 pt.y = GET_Y_LPARAM(lParam); 00202 GetClientRect(hwnd, &rc); 00203 if (!PtInRect(&rc, pt)) { 00204 ReleaseCapture(); 00205 } 00206 return 0; 00207 00208 case WM_CAPTURECHANGED: 00209 NtUserDestroyWindow(hwnd); 00210 return 0; 00211 00212 case WM_NCDESTROY: 00213 NtUserKillTimer(hwnd, TIMERID); 00214 00215 prdr->pfnReaderModeProc(prdr->lParam, RDRCODE_END, 0, 0); 00216 00217 if (prdr->hbm != NULL) { 00218 DeleteObject(prdr->hbm); 00219 } 00220 UserLocalFree(prdr); 00221 return 0; 00222 00223 case WM_CREATE: 00224 if ((prdr = UserLocalAlloc(HEAP_ZERO_MEMORY, sizeof(READERINFO))) == NULL) 00225 return -1; 00226 00227 pcs = (LPCREATESTRUCT)lParam; 00228 prdrm = (PREADERMODE)pcs->lpCreateParams; 00229 RtlCopyMemory(prdr, prdrm, sizeof(READERMODE)); 00230 SetWindowLongPtr(hwnd, 0, (LONG_PTR)prdr); 00231 00232 if (prdr->pfnReaderModeProc == NULL) { 00233 return -1; 00234 } 00235 00236 if (FReader2Dim(prdr)) { 00237 nBitmap = OBM_RDR2DIM; 00238 } else if (FReaderVert(prdr)) { 00239 nBitmap = OBM_RDRVERT; 00240 } else if (FReaderHorz(prdr)) { 00241 nBitmap = OBM_RDRHORZ; 00242 } else { 00243 return -1; 00244 } 00245 00246 SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW); 00247 SetWindowLong(hwnd, GWL_STYLE, WS_POPUP | WS_CLIPSIBLINGS); 00248 00249 prdr->hbm = LoadBitmap(hmodUser, MAKEINTRESOURCE(nBitmap)); 00250 if (prdr->hbm == NULL || 00251 GetObject(prdr->hbm, sizeof(BITMAP), &bmp) == 0) { 00252 return -1; 00253 } 00254 00255 if (prdr->pfnReaderModeProc(prdr->lParam, RDRCODE_START, 0, 0) == 0) { 00256 return -1; 00257 } 00258 00259 prdr->dxBmp = bmp.bmWidth; 00260 prdr->dyBmp = bmp.bmHeight; 00261 00262 cx = bmp.bmWidth + 1; 00263 cy = bmp.bmHeight + 1; 00264 00265 GetCursorPos(&pt); 00266 pt.x -= cx/2; 00267 pt.y -= cy/2; 00268 00269 if ((hrgn = CreateEllipticRgn(0, 0, cx, cy)) != NULL) { 00270 SetWindowRgn(hwnd, hrgn, FALSE); 00271 } 00272 00273 NtUserSetWindowPos(hwnd, HWND_TOPMOST, pt.x, pt.y, cx, cy, 00274 SWP_SHOWWINDOW | SWP_NOACTIVATE); 00275 00276 NtUserSetCapture(hwnd); 00277 NtUserSetFocus(hwnd); 00278 NtUserSetTimer(hwnd, TIMERID, 10, NULL); 00279 return 0; 00280 00281 case WM_ERASEBKGND: 00282 hdc = (HDC)wParam; 00283 00284 if ((hdcMem = CreateCompatibleDC(hdc)) == NULL) 00285 return FALSE; 00286 00287 SelectObject(hdcMem, prdr->hbm); 00288 hpen = CreatePen(PS_SOLID, 1, RGB(0, 0, 0)); 00289 hpenOld = (HPEN)SelectObject(hdc, hpen); 00290 hbrOld = (HBRUSH)SelectObject(hdc, GetStockObject(NULL_BRUSH)); 00291 00292 BitBlt(hdc, 0, 0, prdr->dxBmp, prdr->dyBmp, hdcMem, 0, 0, SRCCOPY); 00293 Ellipse(hdc, 0, 0, prdr->dxBmp, prdr->dyBmp); 00294 00295 SelectObject(hdc, hpenOld); 00296 SelectObject(hdc, hbrOld); 00297 00298 DeleteObject(hpen); 00299 DeleteObject(hdcMem); 00300 return TRUE; 00301 } 00302 00303 return DefWindowProc(hwnd, msg, wParam, lParam); 00304 } 00305 00306 /***************************************************************************\ 00307 * ReaderProcInternal 00308 * 00309 \***************************************************************************/ 00310 00311 LONG ReaderProcInternal(LPARAM lParam, int nCode, int dx, int dy) 00312 { 00313 DWORD dwDelay; 00314 UINT uMsg, uCode; 00315 int n, nAbs; 00316 00317 if (nCode != RDRCODE_SCROLL) 00318 return TRUE; 00319 00320 if (dy != 0) { 00321 uCode = SB_LINEUP; 00322 uMsg = WM_VSCROLL; 00323 n = dy; 00324 } else { 00325 uCode = SB_LINELEFT; 00326 uMsg = WM_HSCROLL; 00327 n = dx; 00328 } 00329 00330 nAbs = abs(n); 00331 if (nAbs >= 120) { 00332 uCode += 2; 00333 dwDelay = 0; 00334 } else { 00335 dwDelay = 1000 - (nAbs / 2) * 15; 00336 } 00337 00338 if (n > 0) { 00339 uCode += 1; 00340 } 00341 00342 SendMessage((HWND)lParam, uMsg, MAKELONG(uCode, dwDelay), 0); 00343 UpdateWindow((HWND)lParam); 00344 return TRUE; 00345 } 00346 00347 /***************************************************************************\ 00348 * EnterReaderMode 00349 * 00350 \***************************************************************************/ 00351 00352 #define READERCLASS L"User32_ReaderMode" 00353 ATOM gatomReaderMode = 0; 00354 00355 BOOL EnterReaderMode(PREADERMODE prdrm) 00356 { 00357 WNDCLASSEX wce; 00358 00359 if (GetCapture() != NULL) 00360 return FALSE; 00361 00362 if (gatomReaderMode == 0) { 00363 wce.cbSize = sizeof(wce); 00364 wce.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; 00365 wce.lpfnWndProc = ReaderWndProc; 00366 wce.cbClsExtra = 0; 00367 wce.cbWndExtra = sizeof(PREADERINFO); 00368 wce.hInstance = hmodUser; 00369 wce.hIcon = NULL; 00370 wce.hCursor = LoadCursor(NULL, IDC_ARROW); 00371 wce.hbrBackground = GetStockObject(WHITE_BRUSH); 00372 wce.lpszMenuName = NULL; 00373 wce.lpszClassName = READERCLASS; 00374 wce.hIconSm = NULL; 00375 00376 if ((gatomReaderMode = RegisterClassExWOWW(&wce, NULL, FNID_DDE_BIT)) == 0) { 00377 RIPMSG0(RIP_WARNING, "EnterReaderMode: failed to register ReaderMode"); 00378 return 0; 00379 } 00380 } 00381 00382 return (_CreateWindowEx(0, READERCLASS, NULL, 0, 0, 0, 0, 0, 00383 NULL, NULL, hmodUser, (PVOID)prdrm, 0) != NULL); 00384 } 00385 00386 /***************************************************************************\ 00387 * FScrollEnabled 00388 * 00389 \***************************************************************************/ 00390 00391 BOOL FScrollEnabled(PWND pwnd, BOOL fVert) 00392 { 00393 PSBINFO pw; 00394 int nFlags; 00395 00396 if (!TestWF(pwnd, fVert ? WFVPRESENT : WFHPRESENT)) 00397 return FALSE; 00398 00399 if ((pw = (PSBINFO)REBASEALWAYS(pwnd, pSBInfo)) == NULL) 00400 return FALSE; 00401 00402 nFlags = fVert ? (pw->WSBflags >> 2) : pw->WSBflags; 00403 00404 if ((nFlags & SB_DISABLE_MASK) == SB_DISABLE_MASK) 00405 return FALSE; 00406 00407 return TRUE; 00408 } 00409 00410 /***************************************************************************\ 00411 * EnterReaderModeHelper 00412 * 00413 \***************************************************************************/ 00414 00415 BOOL EnterReaderModeHelper(HWND hwnd) 00416 { 00417 PWND pwnd = ValidateHwnd(hwnd); 00418 READERMODE rdrm; 00419 00420 rdrm.cbSize = sizeof(READERMODE); 00421 rdrm.pfnReaderModeProc = ReaderProcInternal; 00422 rdrm.lParam = (LPARAM)hwnd; 00423 rdrm.dwFlags = 0; 00424 00425 if (FScrollEnabled(pwnd, TRUE)) { 00426 rdrm.dwFlags |= RDRMODE_VERT; 00427 } 00428 if (FScrollEnabled(pwnd, FALSE)) { 00429 rdrm.dwFlags |= RDRMODE_HORZ; 00430 } 00431 00432 return EnterReaderMode(&rdrm); 00433 }

Generated on Sat May 15 19:41:37 2004 for test by doxygen 1.3.7