Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

map.c

Go to the documentation of this file.
00001 /*
00002  * PROJECT:     ReactOS Character Map
00003  * LICENSE:     GPL - See COPYING in the top level directory
00004  * FILE:        base/applications/charmap/map.c
00005  * PURPOSE:     class implementation for painting glyph region
00006  * COPYRIGHT:   Copyright 2007 Ged Murphy <gedmurphy@reactos.org>
00007  *
00008  */
00009 
00010 #include <precomp.h>
00011 
00012 static const WCHAR szMapWndClass[] = L"FontMapWnd";
00013 static const WCHAR szLrgCellWndClass[] = L"LrgCellWnd";
00014 
00015 static
00016 VOID
00017 TagFontToCell(PCELL pCell,
00018               WCHAR ch)
00019 {
00020     pCell->ch = ch;
00021 }
00022 
00023 
00024 static
00025 VOID
00026 SetGrid(PMAP infoPtr)
00027 {
00028     INT x, y;
00029 
00030     for (y = 0; y < YCELLS; y++)
00031     for (x = 0; x < XCELLS; x++)
00032     {
00033         infoPtr->Cells[y][x].CellExt.left = x * infoPtr->CellSize.cx + 1;
00034         infoPtr->Cells[y][x].CellExt.top = y * infoPtr->CellSize.cy + 1;
00035         infoPtr->Cells[y][x].CellExt.right = (x + 1) * infoPtr->CellSize.cx + 2;
00036         infoPtr->Cells[y][x].CellExt.bottom = (y + 1) * infoPtr->CellSize.cy + 2;
00037 
00038         CopyRect(&infoPtr->Cells[y][x].CellInt,
00039                  &infoPtr->Cells[y][x].CellExt);
00040 
00041         InflateRect(&infoPtr->Cells[y][x].CellInt,
00042                     -1,
00043                     -1);
00044     }
00045 }
00046 
00047 static
00048 VOID
00049 DrawActiveCell(PMAP infoPtr,
00050                HDC hdc)
00051 {
00052     Rectangle(hdc,
00053               infoPtr->pActiveCell->CellInt.left,
00054               infoPtr->pActiveCell->CellInt.top,
00055               infoPtr->pActiveCell->CellInt.right,
00056               infoPtr->pActiveCell->CellInt.bottom);
00057 
00058 }
00059 
00060 
00061 static
00062 VOID
00063 DrawGrid(PMAP infoPtr,
00064          PAINTSTRUCT *ps)
00065 {
00066     INT x, y;
00067     RECT rc;
00068     PCELL Cell;
00069 
00070     for (y = 0; y < YCELLS; y++)
00071     for (x = 0; x < XCELLS; x++)
00072     {
00073         Cell = &infoPtr->Cells[y][x];
00074 
00075         if (!IntersectRect(&rc,
00076                            &ps->rcPaint,
00077                            &Cell->CellExt))
00078         {
00079             continue;
00080         }
00081 
00082         Rectangle(ps->hdc,
00083                   Cell->CellExt.left,
00084                   Cell->CellExt.top,
00085                   Cell->CellExt.right,
00086                   Cell->CellExt.bottom);
00087 
00088         if (infoPtr->pActiveCell == Cell)
00089         {
00090             DrawActiveCell(infoPtr, ps->hdc);
00091         }
00092     }
00093 }
00094 
00095 
00096 static
00097 VOID
00098 FillGrid(PMAP infoPtr,
00099          PAINTSTRUCT *ps)
00100 {
00101     HFONT hOldFont;
00102     WCHAR ch;
00103     INT x, y;
00104     RECT rc;
00105     PCELL Cell;
00106 
00107     hOldFont = SelectObject(ps->hdc,
00108                             infoPtr->hFont);
00109 
00110     for (y = 0; y < YCELLS; y++)
00111     for (x = 0; x < XCELLS; x++)
00112     {
00113         Cell = &infoPtr->Cells[y][x];
00114 
00115         if (!IntersectRect(&rc,
00116                            &ps->rcPaint,
00117                            &Cell->CellExt))
00118         {
00119             continue;
00120         }
00121 
00122         ch = (WCHAR)((XCELLS * (y + infoPtr->iYStart)) + x);
00123 
00124         TagFontToCell(Cell, ch);
00125 
00126         DrawTextW(ps->hdc,
00127                   &ch,
00128                   1,
00129                   &Cell->CellInt,
00130                   DT_CENTER | DT_VCENTER | DT_SINGLELINE);
00131     }
00132 
00133     SelectObject(ps->hdc,
00134                  hOldFont);
00135 }
00136 
00137 
00138 static
00139 BOOL
00140 CreateLargeCell(PMAP infoPtr)
00141 {
00142     RECT rLarge;
00143 
00144     CopyRect(&rLarge,
00145              &infoPtr->pActiveCell->CellExt);
00146 
00147     MapWindowPoints(infoPtr->hMapWnd,
00148                     infoPtr->hParent,
00149                     (VOID*)&rLarge,
00150                     2);
00151 
00152     InflateRect(&rLarge,
00153                 XLARGE - XCELLS,
00154                 YLARGE - YCELLS);
00155 
00156     infoPtr->hLrgWnd = CreateWindowExW(0,
00157                                        szLrgCellWndClass,
00158                                        NULL,
00159                                        WS_CHILDWINDOW | WS_VISIBLE,
00160                                        rLarge.left,
00161                                        rLarge.top,
00162                                        rLarge.right - rLarge.left,
00163                                        rLarge.bottom - rLarge.top,
00164                                        infoPtr->hParent,
00165                                        NULL,
00166                                        hInstance,
00167                                        infoPtr);
00168     if (!infoPtr->hLrgWnd)
00169         return FALSE;
00170 
00171     return TRUE;
00172 }
00173 
00174 
00175 static
00176 VOID
00177 MoveLargeCell(PMAP infoPtr)
00178 {
00179     RECT rLarge;
00180 
00181     CopyRect(&rLarge,
00182              &infoPtr->pActiveCell->CellExt);
00183 
00184     MapWindowPoints(infoPtr->hMapWnd,
00185                     infoPtr->hParent,
00186                     (VOID*)&rLarge,
00187                     2);
00188 
00189     InflateRect(&rLarge,
00190                 XLARGE - XCELLS,
00191                 YLARGE - YCELLS);
00192 
00193     MoveWindow(infoPtr->hLrgWnd,
00194                rLarge.left,
00195                rLarge.top,
00196                rLarge.right - rLarge.left,
00197                rLarge.bottom - rLarge.top,
00198                TRUE);
00199 
00200     InvalidateRect(infoPtr->hLrgWnd,
00201                    NULL,
00202                    TRUE);
00203 }
00204 
00205 
00206 static
00207 VOID
00208 SetFont(PMAP infoPtr,
00209         LPWSTR lpFontName)
00210 {
00211     HDC hdc;
00212 
00213     /* Destroy Zoom window, since it was created with older font */
00214     DestroyWindow(infoPtr->hLrgWnd);
00215     infoPtr->hLrgWnd = NULL;
00216 
00217     if (infoPtr->hFont)
00218         DeleteObject(infoPtr->hFont);
00219 
00220     ZeroMemory(&infoPtr->CurrentFont,
00221                sizeof(LOGFONTW));
00222 
00223     hdc = GetDC(infoPtr->hMapWnd);
00224     infoPtr->CurrentFont.lfHeight = GetDeviceCaps(hdc,
00225                                                   LOGPIXELSY) / 5;
00226     ReleaseDC(infoPtr->hMapWnd, hdc);
00227 
00228     infoPtr->CurrentFont.lfCharSet =  DEFAULT_CHARSET;
00229     wcscpy(infoPtr->CurrentFont.lfFaceName,
00230            lpFontName);
00231 
00232     infoPtr->hFont = CreateFontIndirectW(&infoPtr->CurrentFont);
00233 
00234     InvalidateRect(infoPtr->hMapWnd,
00235                    NULL,
00236                    TRUE);
00237 
00238     /* Test if zoom window must be reopened */
00239     if (infoPtr->pActiveCell != NULL &&
00240         infoPtr->pActiveCell->bLarge)
00241     {
00242         CreateLargeCell(infoPtr);
00243     }
00244 }
00245 
00246 
00247 static
00248 LRESULT
00249 NotifyParentOfSelection(PMAP infoPtr,
00250                         UINT code,
00251                         WCHAR ch)
00252 {
00253     LRESULT Ret = 0;
00254 
00255     if (infoPtr->hParent != NULL)
00256     {
00257         DWORD dwIdc = GetWindowLongPtr(infoPtr->hMapWnd, GWLP_ID);
00258         /*
00259          * Push directly into the event queue instead of waiting
00260          * the parent to be unlocked.
00261          * High word of LPARAM is still available for future needs...
00262          */
00263         Ret = PostMessage(infoPtr->hParent,
00264                           WM_COMMAND,
00265                           MAKELPARAM((WORD)dwIdc, (WORD)code),
00266                           (LPARAM)LOWORD(ch));
00267     }
00268 
00269     return Ret;
00270 }
00271 
00272 
00273 static
00274 VOID
00275 OnClick(PMAP infoPtr,
00276         WORD ptx,
00277         WORD pty)
00278 {
00279     POINT pt;
00280     INT x, y;
00281 
00282     pt.x = ptx;
00283     pt.y = pty;
00284 
00285     for (x = 0; x < XCELLS; x++)
00286     for (y = 0; y < YCELLS; y++)
00287     {
00288         if (PtInRect(&infoPtr->Cells[y][x].CellInt,
00289                      pt))
00290         {
00291             /* if the cell is not already active */
00292             if (!infoPtr->Cells[y][x].bActive)
00293             {
00294                 /* set previous active cell to inactive */
00295                 if (infoPtr->pActiveCell)
00296                 {
00297                     /* invalidate normal cells, required when
00298                      * moving a small active cell via keyboard */
00299                     if (!infoPtr->pActiveCell->bLarge)
00300                     {
00301                         InvalidateRect(infoPtr->hMapWnd,
00302                                        &infoPtr->pActiveCell->CellInt,
00303                                        TRUE);
00304                     }
00305 
00306                     infoPtr->pActiveCell->bActive = FALSE;
00307                     infoPtr->pActiveCell->bLarge = FALSE;
00308                 }
00309 
00310                 /* set new cell to active */
00311                 infoPtr->pActiveCell = &infoPtr->Cells[y][x];
00312                 infoPtr->pActiveCell->bActive = TRUE;
00313                 infoPtr->pActiveCell->bLarge = TRUE;
00314                 if (infoPtr->hLrgWnd)
00315                     MoveLargeCell(infoPtr);
00316                 else
00317                     CreateLargeCell(infoPtr);
00318             }
00319             else
00320             {
00321                 /* flick between large and small */
00322                 if (infoPtr->pActiveCell->bLarge)
00323                 {
00324                     DestroyWindow(infoPtr->hLrgWnd);
00325                     infoPtr->hLrgWnd = NULL;
00326                 }
00327                 else
00328                 {
00329                     CreateLargeCell(infoPtr);
00330                 }
00331 
00332                 infoPtr->pActiveCell->bLarge = (infoPtr->pActiveCell->bLarge) ? FALSE : TRUE;
00333             }
00334 
00335             break;
00336         }
00337     }
00338 }
00339 
00340 
00341 static
00342 BOOL
00343 OnCreate(PMAP infoPtr,
00344          HWND hwnd,
00345          HWND hParent)
00346 {
00347     RECT rc;
00348     BOOL Ret = FALSE;
00349 
00350     infoPtr = HeapAlloc(GetProcessHeap(),
00351                         0,
00352                         sizeof(MAP));
00353     if (infoPtr)
00354     {
00355         SetLastError(0);
00356         SetWindowLongPtrW(hwnd,
00357                           0,
00358                           (DWORD_PTR)infoPtr);
00359         if (GetLastError() == 0)
00360         {
00361             ZeroMemory(infoPtr,
00362                        sizeof(MAP));
00363 
00364             infoPtr->hMapWnd = hwnd;
00365             infoPtr->hParent = hParent;
00366 
00367             GetClientRect(hwnd, &rc);
00368             infoPtr->ClientSize.cx = rc.right;
00369             infoPtr->ClientSize.cy = rc.bottom;
00370             infoPtr->CellSize.cx = infoPtr->ClientSize.cx / XCELLS;
00371             infoPtr->CellSize.cy = infoPtr->ClientSize.cy / YCELLS;
00372 
00373             infoPtr->pActiveCell = NULL;
00374 
00375             SetGrid(infoPtr);
00376 
00377             SetScrollRange(hwnd, SB_VERT, 0, 255, FALSE);
00378             SetScrollPos(hwnd, SB_VERT, 0, TRUE);
00379 
00380             Ret = TRUE;
00381         }
00382     }
00383 
00384     return Ret;
00385 }
00386 
00387 
00388 static
00389 VOID
00390 OnVScroll(PMAP infoPtr,
00391           INT Value,
00392           INT Pos)
00393 {
00394     INT iYDiff, iOldYStart = infoPtr->iYStart;
00395 
00396     switch (Value)
00397     {
00398         case SB_LINEUP:
00399             infoPtr->iYStart -=  1;
00400             break;
00401 
00402         case SB_LINEDOWN:
00403             infoPtr->iYStart +=  1;
00404             break;
00405 
00406         case SB_PAGEUP:
00407             infoPtr->iYStart -= YCELLS;
00408             break;
00409 
00410         case SB_PAGEDOWN:
00411             infoPtr->iYStart += YCELLS;
00412             break;
00413 
00414         case SB_THUMBTRACK:
00415             infoPtr->iYStart = Pos;
00416             break;
00417 
00418        default:
00419             break;
00420        }
00421 
00422     infoPtr->iYStart = max(0,
00423                          min(infoPtr->iYStart, 255*16));
00424 
00425     iYDiff = iOldYStart - infoPtr->iYStart;
00426     if (iYDiff)
00427     {
00428         if (infoPtr->hLrgWnd != NULL)
00429         {
00430             ShowWindow(infoPtr->hLrgWnd, SW_HIDE);
00431         }
00432 
00433         SetScrollPos(infoPtr->hMapWnd,
00434                      SB_VERT,
00435                      infoPtr->iYStart,
00436                      TRUE);
00437 
00438         if (abs(iYDiff) < YCELLS)
00439         {
00440             RECT rect;
00441             GetClientRect(infoPtr->hMapWnd, &rect);
00442             rect.top += 2;
00443             rect.bottom -= 2;
00444             ScrollWindowEx(infoPtr->hMapWnd,
00445                            0,
00446                            iYDiff * infoPtr->CellSize.cy,
00447                            &rect,
00448                            &rect,
00449                            NULL,
00450                            NULL,
00451                            SW_INVALIDATE);
00452         }
00453         else
00454         {
00455             InvalidateRect(infoPtr->hMapWnd,
00456                            NULL,
00457                            TRUE);
00458         }
00459 
00460         if (infoPtr->hLrgWnd != NULL)
00461         {
00462             ShowWindow(infoPtr->hLrgWnd, SW_SHOW);
00463         }
00464     }
00465 }
00466 
00467 
00468 static
00469 VOID
00470 OnPaint(PMAP infoPtr,
00471         WPARAM wParam)
00472 {
00473     PAINTSTRUCT ps;
00474     HDC hdc;
00475 
00476 
00477     if (wParam != 0)
00478     {
00479         if (!GetUpdateRect(infoPtr->hMapWnd,
00480                            &ps.rcPaint,
00481                            TRUE))
00482         {
00483             return;
00484         }
00485         hdc = (HDC)wParam;
00486     }
00487     else
00488     {
00489         hdc = BeginPaint(infoPtr->hMapWnd,
00490                          &ps);
00491         if (hdc == NULL)
00492         {
00493             return;
00494         }
00495     }
00496 
00497     DrawGrid(infoPtr, &ps);
00498 
00499     FillGrid(infoPtr, &ps);
00500 
00501     if (wParam == 0)
00502     {
00503         EndPaint(infoPtr->hMapWnd,
00504                  &ps);
00505     }
00506 }
00507 
00508 
00509 LRESULT
00510 CALLBACK
00511 MapWndProc(HWND hwnd,
00512            UINT uMsg,
00513            WPARAM wParam,
00514            LPARAM lParam)
00515 {
00516     PMAP infoPtr;
00517     LRESULT Ret = 0;
00518 
00519     infoPtr = (PMAP)GetWindowLongPtrW(hwnd,
00520                                       0);
00521 
00522     switch (uMsg)
00523     {
00524         case WM_CREATE:
00525         {
00526             if (!OnCreate(infoPtr,
00527                           hwnd,
00528                           ((LPCREATESTRUCTW)lParam)->hwndParent))
00529             {
00530                 return (LRESULT)-1;
00531             }
00532 
00533             break;
00534         }
00535 
00536         case WM_LBUTTONDOWN:
00537         {
00538             OnClick(infoPtr,
00539                     LOWORD(lParam),
00540                     HIWORD(lParam));
00541 
00542             break;
00543         }
00544 
00545         case WM_LBUTTONDBLCLK:
00546         {
00547             NotifyParentOfSelection(infoPtr,
00548                                     FM_SETCHAR,
00549                                     infoPtr->pActiveCell->ch);
00550 
00551 
00552             break;
00553         }
00554 
00555         case WM_VSCROLL:
00556         {
00557             OnVScroll(infoPtr,
00558                       LOWORD(wParam),
00559                       HIWORD(wParam));
00560 
00561             break;
00562         }
00563 
00564         case FM_SETFONT:
00565             SetFont(infoPtr, (LPWSTR)lParam);
00566             break;
00567 
00568         case FM_GETCHAR:
00569         {
00570             if (!infoPtr->pActiveCell) return 0;
00571             return infoPtr->pActiveCell->ch;
00572         }
00573 
00574         case FM_GETHFONT:
00575             return (LRESULT)infoPtr->hFont;
00576 
00577         case WM_PAINT:
00578         {
00579             OnPaint(infoPtr,
00580                     wParam);
00581             break;
00582         }
00583 
00584         case WM_DESTROY:
00585         {
00586             DeleteObject(infoPtr->hFont);
00587             HeapFree(GetProcessHeap(),
00588                      0,
00589                      infoPtr);
00590             SetWindowLongPtrW(hwnd,
00591                               0,
00592                               (DWORD_PTR)NULL);
00593             break;
00594         }
00595 
00596         default:
00597         {
00598             Ret = DefWindowProcW(hwnd,
00599                                  uMsg,
00600                                  wParam,
00601                                  lParam);
00602             break;
00603         }
00604     }
00605 
00606     return Ret;
00607 }
00608 
00609 
00610 BOOL
00611 RegisterMapClasses(HINSTANCE hInstance)
00612 {
00613     WNDCLASSW wc = {0};
00614 
00615     wc.style = CS_DBLCLKS;
00616     wc.lpfnWndProc = MapWndProc;
00617     wc.cbWndExtra = sizeof(PMAP);
00618     wc.hInstance = hInstance;
00619     wc.hCursor = LoadCursorW(NULL,
00620                             (LPWSTR)IDC_ARROW);
00621     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
00622     wc.lpszClassName = szMapWndClass;
00623 
00624     if (RegisterClassW(&wc))
00625     {
00626         wc.lpfnWndProc = LrgCellWndProc;
00627         wc.cbWndExtra = 0;
00628         wc.lpszClassName = szLrgCellWndClass;
00629 
00630         return RegisterClassW(&wc) != 0;
00631     }
00632 
00633     return FALSE;
00634 }
00635 
00636 VOID
00637 UnregisterMapClasses(HINSTANCE hInstance)
00638 {
00639     UnregisterClassW(szMapWndClass,
00640                     hInstance);
00641 
00642     UnregisterClassW(szLrgCellWndClass,
00643                     hInstance);
00644 }

Generated on Thu Feb 9 04:38:59 2012 for ReactOS by doxygen 1.6.3

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.