Annotation of mstools/samples/sdktools/windiff/bar.c, revision 1.1.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.