Annotation of mstools/samples/sdktools/windiff/bar.c, revision 1.1

1.1     ! root        1: 
        !             2: /******************************************************************************\
        !             3: *       This is a part of the Microsoft Source Code Samples. 
        !             4: *       Copyright (C) 1993 Microsoft Corporation.
        !             5: *       All rights reserved. 
        !             6: *       This source code is only intended as a supplement to 
        !             7: *       Microsoft Development Tools and/or WinHelp documentation.
        !             8: *       See these sources for detailed information regarding the 
        !             9: *       Microsoft samples programs.
        !            10: \******************************************************************************/
        !            11: 
        !            12: /****************************** Module Header *******************************
        !            13: * Module Name: BAR.C
        !            14: *
        !            15: * This module contains functions for bar window 
        !            16: * graphically showing two lists of sections and showing 
        !            17: * colored vertical bars for the sections of text,
        !            18: * with linking lines for the sections that are the same.
        !            19: *
        !            20: * Functions:
        !            21: *
        !            22: * BarWndProc()
        !            23: * BarPaint()
        !            24: * DrawSection()
        !            25: * DrawLink()
        !            26: * BarClick() 
        !            27: * InitBarClass()
        !            28: * BarDrawPosition()
        !            29: * 
        !            30: * Comments:
        !            31: *
        !            32: ****************************************************************************/
        !            33: 
        !            34: #include <windows.h>
        !            35: #include <commdlg.h>
        !            36: 
        !            37: #include "gutils.h"
        !            38: #include "table.h"
        !            39: #include "state.h"
        !            40: #include "wdiffrc.h"
        !            41: #include "windiff.h"
        !            42: #include "list.h"
        !            43: #include "line.h"
        !            44: #include "scandir.h"
        !            45: #include "file.h"
        !            46: #include "section.h"
        !            47: #include "compitem.h"
        !            48: #include "complist.h"
        !            49: #include "view.h"
        !            50: 
        !            51: 
        !            52: long APIENTRY BarWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam);
        !            53: void BarPaint(HWND hwnd);
        !            54: void DrawSection(HDC hdc, int cx, int cy, int lines, SECTION sec, int sidecode);
        !            55: void DrawLink(HDC hdc, int cx, int cy, int lines, SECTION sec);
        !            56: void BarClick(HWND hwnd, int x, int y);
        !            57: 
        !            58: 
        !            59: HPEN hpenSame, hpenLeft, hpenRight;
        !            60: HBRUSH hbrSame, hbrLeft, hbrRight;
        !            61: HBRUSH hbrSideBar;
        !            62: 
        !            63: 
        !            64: /***************************************************************************
        !            65:  * Function: InitBarClass
        !            66:  *
        !            67:  * Purpose:
        !            68:  *
        !            69:  * Create bar window class
        !            70:  */
        !            71: BOOL
        !            72: InitBarClass(HINSTANCE hInstance)
        !            73: {
        !            74:         WNDCLASS    wc;
        !            75:         BOOL resp;
        !            76: 
        !            77: 
        !            78: 
        !            79:         wc.style = CS_HREDRAW | CS_VREDRAW;
        !            80:         wc.lpfnWndProc = BarWndProc;
        !            81:         wc.cbClsExtra = 0;
        !            82:         wc.cbWndExtra = 0;
        !            83:         wc.hInstance = hInstance;
        !            84:         wc.hIcon = NULL;
        !            85:         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
        !            86:         wc.hbrBackground = GetStockObject(WHITE_BRUSH);
        !            87:         wc.lpszClassName = "BarClass";
        !            88:         wc.lpszMenuName = NULL;
        !            89: 
        !            90:         resp = RegisterClass(&wc);
        !            91: 
        !            92:         return(resp);
        !            93: }
        !            94: 
        !            95: 
        !            96: 
        !            97: /***************************************************************************
        !            98:  * Function: BarWndProc
        !            99:  *
        !           100:  * Purpose:
        !           101:  *
        !           102:  * Window procedure supporting bar window
        !           103:  *
        !           104:  */
        !           105: 
        !           106: long APIENTRY
        !           107: BarWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam)
        !           108: {
        !           109: 
        !           110:         switch(message) {
        !           111: 
        !           112: 
        !           113:         case WM_CREATE:
        !           114: 
        !           115:                 hpenSame = CreatePen(PS_SOLID, 1, RGB(0,0,0));
        !           116:                 hbrSame = CreateSolidBrush(RGB(255,255,255));
        !           117: 
        !           118:                 hpenLeft = CreatePen(PS_SOLID, 1, rgb_barleft);
        !           119:                 hbrLeft = CreateSolidBrush(rgb_barleft);
        !           120: 
        !           121:                 hpenRight = CreatePen(PS_SOLID, 1, rgb_barright);
        !           122:                 hbrRight = CreateSolidBrush(rgb_barright);
        !           123: 
        !           124:                 hbrSideBar = CreateSolidBrush(rgb_barcurrent);
        !           125:                 break;
        !           126: 
        !           127:         case WM_DESTROY:
        !           128:                 DeleteObject(hpenSame);
        !           129:                 DeleteObject(hpenLeft);
        !           130:                 DeleteObject(hpenRight);
        !           131:                 DeleteObject(hbrSame);
        !           132:                 DeleteObject(hbrLeft);
        !           133:                 DeleteObject(hbrRight);
        !           134:                 DeleteObject(hbrSideBar);
        !           135:                 break;
        !           136: 
        !           137:         case WM_PAINT:
        !           138:                 BarPaint(hWnd);
        !           139:                 break;
        !           140: 
        !           141:         case WM_LBUTTONDOWN:
        !           142:                 BarClick(hWnd, LOWORD(lParam), HIWORD(lParam));
        !           143:                 break;
        !           144: 
        !           145:         default:
        !           146:                 return(DefWindowProc(hWnd, message, wParam, lParam));
        !           147:         }
        !           148:         return 0;
        !           149: }
        !           150: 
        !           151: /***************************************************************************
        !           152:  * Function: BarDrawPosition
        !           153:  *
        !           154:  * Purpose:
        !           155:  *
        !           156:  * Draw the current position as side-bars down the bar window,
        !           157:  * showing which lines from each file are currently in view. HDC can be
        !           158:  * NULL (we get one ourselves if so). If bErase is true, we clear
        !           159:  * the previous side-bars first.
        !           160:  *
        !           161:  * This is called from BarPaint when we paint the whole window, and
        !           162:  * from TableServer() whenever it receives a TQ_SCROLL notification that
        !           163:  * the table window has been scrolled.
        !           164:  */
        !           165: void
        !           166: BarDrawPosition(HWND hwndBar, HDC hdcIn, BOOL bErase)
        !           167: {
        !           168:         HDC hdc;
        !           169:         int total_lines, cy, cx;
        !           170:         RECT rc, rcLeft, rcRight;
        !           171:         VIEW view;
        !           172:         COMPITEM item;
        !           173:         LIST listleft, listright;
        !           174:         long toprow, endrow, i;
        !           175:         int left_first, left_last, right_first, right_last, linenr;
        !           176: 
        !           177: 
        !           178:         /* get a hdc if we weren't given one */
        !           179:         if (hdcIn == NULL) {
        !           180:                 hdc = GetDC(hwndBar);
        !           181:         } else {
        !           182:                 hdc = hdcIn;
        !           183:         }
        !           184: 
        !           185:         /* set horz position of bars */
        !           186:         GetClientRect(hwndBar, &rc);
        !           187:         cx = (int)(rc.right - rc.left);
        !           188:         cy = (int)(rc.bottom - rc.top);
        !           189: 
        !           190:         /* layout constants are defined as percentages of window width */
        !           191:         rcLeft.left = cx * L_POS_START / 100;
        !           192:         rcRight.left = cx * R_POS_START / 100;
        !           193:         rcLeft.right = rcLeft.left +  (cx * L_POS_WIDTH / 100);
        !           194:         rcRight.right = rcRight.left +  (cx * R_POS_WIDTH / 100);
        !           195: 
        !           196:         /* erase the whole marker section if requested */
        !           197:         if (bErase) {
        !           198:                 rcLeft.top = rc.top;
        !           199:                 rcLeft.bottom = rc.bottom;
        !           200:                 rcRight.top = rc.top;
        !           201:                 rcRight.bottom = rc.bottom;
        !           202: 
        !           203:                 FillRect(hdc, &rcLeft, GetStockObject(WHITE_BRUSH));
        !           204: 
        !           205:                 FillRect(hdc, &rcRight, GetStockObject(WHITE_BRUSH));
        !           206:         }
        !           207: 
        !           208: 
        !           209:         /*
        !           210:          * calculate the vertical scaling - depends on the
        !           211:          * total number of lines shown
        !           212:          */
        !           213: 
        !           214:         /* get the handles to the two lists of sections */
        !           215:         view = (VIEW) SendMessage(hwndClient, TM_CURRENTVIEW, 0, 0);
        !           216:         /* make sure we are in expand mode */
        !           217:         if (view_isexpanded(view) == FALSE) {
        !           218:                 /* get rid of the dc if we made it ourselves */
        !           219:                 if (hdcIn == NULL) {
        !           220:                         ReleaseDC(hwndBar, hdc);
        !           221:                 }
        !           222:                 return;
        !           223:         }
        !           224: 
        !           225:         item = view_getitem(view, 0);
        !           226: 
        !           227:         listleft = compitem_getleftsections(item);
        !           228:         listright = compitem_getrightsections(item);
        !           229: 
        !           230:         /* if there is only one list of sections, draw nothing. The
        !           231:          * picture for a single file is not very exciting.
        !           232:          */
        !           233: 
        !           234:         if ((listleft == NULL) || (listright == NULL)) {
        !           235:                 /* get rid of the dc if we made it ourselves */
        !           236:                 if (hdcIn == NULL) {
        !           237:                         ReleaseDC(hwndBar, hdc);
        !           238:                 }
        !           239:                 return;
        !           240:         }
        !           241: 
        !           242:         /* take the longest of the two files and use this
        !           243:          * for vertical scaling. the scale is such that the longest file
        !           244:          * *just fits*.
        !           245:          */
        !           246:         total_lines = line_getlinenr(section_getlastline(List_Last(listleft)));
        !           247:         total_lines = max(total_lines,
        !           248:                        (int) line_getlinenr(section_getlastline(List_Last(listright))));
        !           249: 
        !           250: 
        !           251:         /* get the current top row and nr of rows visible */
        !           252:         toprow = SendMessage(hwndRCD, TM_TOPROW, FALSE, 0);
        !           253:         endrow = SendMessage(hwndRCD, TM_ENDROW, FALSE, 0);
        !           254:         endrow = min(endrow, view_getrowcount(view)-1);
        !           255: 
        !           256: 
        !           257: 
        !           258:         /*
        !           259:          * find the first and last line nrs from each file currently visible.
        !           260:          *
        !           261:          */
        !           262:         left_first = left_last = right_first = right_last = 0;
        !           263: 
        !           264:         for (i = toprow; i <= endrow; i++) {
        !           265:                 linenr = view_getlinenr_left(view, i);
        !           266: 
        !           267:                 if (linenr > 0) {
        !           268: 
        !           269:                         if (left_first == 0) {
        !           270:                                 left_first = linenr;
        !           271:                         }
        !           272:                         left_first = min(left_first, linenr);
        !           273:                         left_last = max(left_last, linenr);
        !           274:                 }
        !           275: 
        !           276:                 linenr = view_getlinenr_right(view, i);
        !           277:                 if (linenr > 0) {
        !           278:                         if (right_first == 0) {
        !           279:                                 right_first = linenr;
        !           280:                         }
        !           281:                         right_first = min(right_first, linenr);
        !           282:                         right_last = max(right_last, linenr);
        !           283:                 }
        !           284: 
        !           285:         }
        !           286: 
        !           287:         /* draw the two markers as thick bars -> elongated rectangles */
        !           288:         rcLeft.top = MulDiv(left_first-1, cy, total_lines);
        !           289:         rcLeft.bottom = MulDiv(left_last, cy, total_lines);
        !           290:         FillRect(hdc, &rcLeft, hbrSideBar);
        !           291: 
        !           292:         rcRight.top = MulDiv(right_first-1, cy, total_lines);
        !           293:         rcRight.bottom = MulDiv(right_last, cy, total_lines);
        !           294:         FillRect(hdc, &rcRight, hbrSideBar);
        !           295: 
        !           296:         /* get rid of the dc if we made it ourselves */
        !           297:         if (hdcIn == NULL) {
        !           298:                 ReleaseDC(hwndBar, hdc);
        !           299:         }
        !           300: 
        !           301: }
        !           302: 
        !           303: 
        !           304: /***************************************************************************
        !           305:  * Function: BarPaint
        !           306:  *
        !           307:  * Purpose:
        !           308:  *
        !           309:  * Paint the bar window 
        !           310:  */
        !           311: void
        !           312: BarPaint(HWND hwnd)
        !           313: {
        !           314:         PAINTSTRUCT ps;
        !           315:         HDC hdc;
        !           316:         VIEW view;
        !           317:         COMPITEM item;
        !           318:         LIST listleft, listright;
        !           319:         SECTION sec;
        !           320:         int total_lines, cx, cy;
        !           321:         RECT rc;
        !           322: 
        !           323:         hdc = BeginPaint(hwnd, &ps);
        !           324: 
        !           325:         /* draw a separator line at the very edge of the window */
        !           326:         GetClientRect(hwnd, &rc);
        !           327:         MoveToEx(hdc, (int)(rc.right-1), rc.top, NULL);
        !           328:         LineTo(hdc, (int)(rc.right-1), rc.bottom);
        !           329: 
        !           330: 
        !           331:         /* first gather information about what is to be displayed */
        !           332: 
        !           333:         /* find the total lines (for horz. scaling) */
        !           334: 
        !           335:         /* get the handles to the two lists of sections */
        !           336:         view = (VIEW) SendMessage(hwndClient, TM_CURRENTVIEW, 0, 0);
        !           337: 
        !           338:         /* make sure we are in expand mode */
        !           339:         if (view_isexpanded(view) == FALSE) {
        !           340:                 return;
        !           341:         }
        !           342: 
        !           343:         item = view_getitem(view, 0);
        !           344: 
        !           345:         listleft = compitem_getleftsections(item);
        !           346:         listright = compitem_getrightsections(item);
        !           347: 
        !           348:         /*
        !           349:          * don't bother if there is only one list - not very interesting
        !           350:          */
        !           351:         if ((listleft == NULL) || (listright == NULL)) {
        !           352:                 EndPaint(hwnd, &ps);
        !           353:                 return;
        !           354:         }
        !           355: 
        !           356:         /* take the longest of the two files and use this
        !           357:          * for vertical scaling. the scale is such that the longest file
        !           358:          * *just fits*.
        !           359:          */
        !           360:         total_lines = (int) line_getlinenr(section_getlastline(List_Last(listleft)));
        !           361:         total_lines = max(total_lines,
        !           362:                        (int) line_getlinenr(section_getlastline(List_Last(listright))));
        !           363: 
        !           364: 
        !           365: 
        !           366:         /* horizontal spacing:
        !           367:          *
        !           368:          * there are two columns, for the left and right files, and a gap
        !           369:          * between them criss-crossed by lines marking the links.
        !           370:          *
        !           371:          * Each of the columns then has three sections, for the
        !           372:          * position marker, the different sections
        !           373:          * and the linked sections. The width and positions of these items
        !           374:          * are defined (in windiff.h) as percentages of the window width.
        !           375:          */
        !           376: 
        !           377:         cx = (int)(rc.right - rc.left);
        !           378:         cy = (int)(rc.bottom - rc.top);
        !           379: 
        !           380: 
        !           381:         /* draw all the left sections and links */
        !           382:         List_TRAVERSE(listleft, sec) {
        !           383:                 DrawSection(hdc, cx, cy, total_lines, sec, STATE_LEFTONLY);
        !           384: 
        !           385:                 if (section_getlink(sec) != NULL) {
        !           386:                         DrawLink(hdc, cx, cy, total_lines, sec);
        !           387:                 }
        !           388:         }
        !           389: 
        !           390:         /* draw all the right sections */
        !           391:         List_TRAVERSE(listright, sec) {
        !           392:                 DrawSection(hdc, cx, cy, total_lines, sec, STATE_RIGHTONLY);
        !           393:         }
        !           394: 
        !           395: 
        !           396: 
        !           397:         /* now draw current position markers */
        !           398:         BarDrawPosition(hwnd, hdc, FALSE);
        !           399: 
        !           400:         EndPaint(hwnd, &ps);
        !           401: }
        !           402: 
        !           403: /***************************************************************************
        !           404:  * Function: DrawSection
        !           405:  *
        !           406:  * Purpose:
        !           407:  *
        !           408:  * Paint a single section 
        !           409:  */
        !           410: void
        !           411: DrawSection(HDC hdc, int cx, int cy, int lines, SECTION sec, int sidecode)
        !           412: {
        !           413:         int x1, y1, x2, y2;
        !           414:         HPEN hpenOld;
        !           415:         HBRUSH hbrOld;
        !           416: 
        !           417:         /* calculate the vertical position from the scaling. the scaling
        !           418:          * is such that the longest file just fits
        !           419:          */
        !           420:         y1 = MulDiv(line_getlinenr(section_getfirstline(sec))- 1, cy, lines);
        !           421:         y2 = MulDiv(line_getlinenr(section_getlastline(sec)), cy, lines);
        !           422: 
        !           423: 
        !           424:         /* left or right  - set bar position and width*/
        !           425:         if (sidecode == STATE_LEFTONLY) {
        !           426:                 if (section_getlink(sec) != NULL) {
        !           427:                         x1 = L_MATCH_START;
        !           428:                         x2 = L_MATCH_WIDTH;
        !           429:                 } else {
        !           430:                         x1 = L_UNMATCH_START;
        !           431:                         x2 = L_UNMATCH_WIDTH;
        !           432:                 }
        !           433:         } else {
        !           434:                 if (section_getlink(sec) != NULL) {
        !           435:                         x1 = R_MATCH_START;
        !           436:                         x2 = R_MATCH_WIDTH;
        !           437:                 } else {
        !           438:                         x1 = R_UNMATCH_START;
        !           439:                         x2 = R_UNMATCH_WIDTH;
        !           440:                 }
        !           441:         }
        !           442:         /* bar position defines are in percentages of the win width (cx) */
        !           443:         x1 = cx * x1 / 100;
        !           444:         x2 = (cx * x2 / 100) + x1;
        !           445: 
        !           446: 
        !           447:         /* select pens and brushes */
        !           448:         if (section_getlink(sec) != NULL) {
        !           449:                 hpenOld = SelectObject(hdc, hpenSame);
        !           450:                 hbrOld = SelectObject(hdc, hbrSame);
        !           451:         } else if (sidecode == STATE_LEFTONLY) {
        !           452:                 hpenOld = SelectObject(hdc, hpenLeft);
        !           453:                 hbrOld = SelectObject(hdc, hbrLeft);
        !           454:         } else {
        !           455:                 hpenOld = SelectObject(hdc, hpenRight);
        !           456:                 hbrOld = SelectObject(hdc, hbrRight);
        !           457:         }
        !           458: 
        !           459:         /* draw the section as a coloured elongated rectangle */
        !           460:         Rectangle(hdc, x1, y1, x2, y2);
        !           461: 
        !           462:         /* de-select the pen and brush in favour of the default */
        !           463:         SelectObject(hdc, hpenOld);
        !           464:         SelectObject(hdc, hbrOld);
        !           465: 
        !           466: }
        !           467: 
        !           468: /***************************************************************************
        !           469:  * Function: DrawLink
        !           470:  *
        !           471:  * Purpose:
        !           472:  *
        !           473:  * Draw a line linking two sections. Indicates a section from each
        !           474:  * file that match each other. psec points to the section in the
        !           475:  * left file.
        !           476:  */
        !           477: void
        !           478: DrawLink(HDC hdc, int cx, int cy, int lines, SECTION sec)
        !           479: {
        !           480:         int x1, y1, x2, y2;
        !           481:         int ybase, yrange;
        !           482:         SECTION other;
        !           483: 
        !           484:         other = section_getlink(sec);
        !           485: 
        !           486:         /* position the link line halfway down the section
        !           487:          * - allow for the case where
        !           488:          * the section is one line (ie halve the co-ords, not the line nr)
        !           489:          */
        !           490:         ybase = MulDiv(line_getlinenr(section_getfirstline(sec)) - 1, cy, lines);
        !           491:         yrange = MulDiv(line_getlinenr(section_getlastline(sec)), cy, lines);
        !           492:         y1 = ((yrange - ybase) / 2) + ybase;
        !           493: 
        !           494:         ybase = MulDiv(line_getlinenr(section_getfirstline(other)) - 1, cy, lines);
        !           495:         yrange = MulDiv(line_getlinenr(section_getlastline(other)), cy, lines);
        !           496:         y2 = ((yrange - ybase) / 2) + ybase;
        !           497: 
        !           498:         /* horizontal layout constants are defined as percentages of the
        !           499:          * window width
        !           500:          */
        !           501:         x1 = cx * (L_MATCH_START + L_MATCH_WIDTH) / 100;
        !           502:         x2 = cx * R_UNMATCH_START / 100;
        !           503: 
        !           504:         MoveToEx(hdc, x1, y1, NULL);
        !           505:         LineTo(hdc, x2, y2);
        !           506: }
        !           507: 
        !           508: 
        !           509: /***************************************************************************
        !           510:  * Function: BarClick
        !           511:  *
        !           512:  * Purpose:
        !           513:  *
        !           514:  * The user has clicked on the bar window. Translate the clicked position into
        !           515:  * a line in one of the files if possible, and scroll the table window to
        !           516:  * show that line.
        !           517:  */
        !           518: void
        !           519: BarClick(HWND hwnd, int x, int y)
        !           520: {
        !           521:         RECT rc;
        !           522:         int xleft, xright;
        !           523:         int linenr, i, this;
        !           524:         BOOL bIsLeft;
        !           525:         int tot_left, tot_right, total_lines;
        !           526:         LIST listleft, listright;
        !           527:         VIEW view;
        !           528:         COMPITEM item;
        !           529:         TableSelection select;
        !           530: 
        !           531: 
        !           532:         /* find size of the window to get horz scaling, and see
        !           533:          * where click was
        !           534:          */
        !           535:         GetClientRect(hwnd, &rc);
        !           536: 
        !           537:         /* was it near either of the bars ? */
        !           538: 
        !           539:         /* horz positioning is in percentages of window width */
        !           540:         xleft = max(L_UNMATCH_START + L_UNMATCH_WIDTH,
        !           541:                      L_MATCH_START + L_MATCH_WIDTH);
        !           542:         xright = min(R_UNMATCH_START, R_MATCH_START);
        !           543:         xleft = xleft * (rc.right - rc.left) / 100;
        !           544:         xright = xright * (rc.right - rc.left) / 100;
        !           545: 
        !           546: 
        !           547:         if (x < xleft) {
        !           548:                 bIsLeft = TRUE;
        !           549:         } else if (x > xright) {
        !           550:                 bIsLeft = FALSE;
        !           551:         } else {
        !           552:                 /* click was between the two bars - ignore it */
        !           553:                 return;
        !           554:         }
        !           555: 
        !           556: 
        !           557:         /* calculate the vertical scaling (based on total lines displayed)
        !           558:          * so that we can convert the y position into a line nr
        !           559:          */
        !           560: 
        !           561:         /* get the handles to the two lists of sections */
        !           562:         view = (VIEW) SendMessage(hwndClient, TM_CURRENTVIEW, 0, 0);
        !           563: 
        !           564:         /* make sure we are in expand mode */
        !           565:         if (view_isexpanded(view) == FALSE) {
        !           566:                 return;
        !           567:         }
        !           568: 
        !           569:         item = view_getitem(view, 0);
        !           570: 
        !           571:         listleft = compitem_getleftsections(item);
        !           572:         listright = compitem_getrightsections(item);
        !           573: 
        !           574:         /* ignore the click if only one list of sections, since in
        !           575:          * this case there is nothing drawn for him to click on.
        !           576:          */
        !           577:         if ((listleft == NULL) || (listright == NULL)) {
        !           578:                 return;
        !           579:         }
        !           580: 
        !           581:         /* take the longest of the two files and use this
        !           582:          * for vertical scaling. the scale is such that the longest file
        !           583:          * *just fits*.
        !           584:          */
        !           585:         tot_left = line_getlinenr(section_getlastline(List_Last(listleft)));
        !           586:         tot_right = line_getlinenr(section_getlastline(List_Last(listright)));
        !           587: 
        !           588:         total_lines = max(tot_left, tot_right);
        !           589: 
        !           590: 
        !           591:         /* convert vertical position into a line nr. The vertical scaling
        !           592:          * can be calculated from knowing that the longest list of
        !           593:          * lines just fits in the window.
        !           594:          */
        !           595:         linenr = (int) (((long) total_lines * y) / (rc.bottom - rc.top)) + 1;
        !           596: 
        !           597:         /* check that the line is valid */
        !           598:         if (bIsLeft) {
        !           599:                 if (linenr > tot_left) {
        !           600:                         return;
        !           601:                 }
        !           602:         } else {
        !           603:                 if (linenr > tot_right) {
        !           604:                         return;
        !           605:                 }
        !           606:         }
        !           607: 
        !           608:         /* search the current view, looking for a row with this
        !           609:          * line nr on the correct side
        !           610:          */
        !           611:         for (i = 0; i < view_getrowcount(view); i++) {
        !           612:                 if (bIsLeft) {
        !           613:                         this = view_getlinenr_left(view,i);
        !           614:                 } else {
        !           615:                         this = view_getlinenr_right(view,i);
        !           616:                 }
        !           617: 
        !           618:                 if (linenr == this) {
        !           619:                         /* found the matching line- select it in the
        !           620:                          * table window
        !           621:                          */
        !           622:                         select.startrow = i;
        !           623:                         select.startcell = 0;
        !           624:                         select.nrows = 1;
        !           625:                         select.ncells = 1;
        !           626:                         SendMessage(hwndRCD, TM_SELECT, 0, (long) (LPSTR)&select);
        !           627:                         return;
        !           628:                 }
        !           629:         }
        !           630: 
        !           631:         windiff_UI(TRUE);
        !           632:         MessageBox(hwndClient, "Line not visible in this view",
        !           633:                 "WinDiff", MB_ICONSTOP|MB_OK);
        !           634:         windiff_UI(FALSE);
        !           635: }
        !           636: 
        !           637: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.