00001
00002
00003
00004
00005
00006
00007
00008
00009
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
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
00050
00051
00052
00053
00054
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
00137
00138
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
00154
00155
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
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
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
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
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 }