⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 view.c

📁 <Win2k系统编程>源码.次数为国人自编,内容丰富,还是不错的.
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************** Module Header *******************************
* Module Name: VIEW.C
*
* Maps rows in window to items in COMPLIST
*
* Functions:
*
* view_new()
* view_setcomplist()
* view_getcomplist()
* view_close()
* view_delete()
* view_outline()
* view_expand()
* view_gettext()
* view_getlinenr_left()
* view_getlinenr_right()
* view_getwidth()
* view_getrowcount()
* view_getstate()
* view_getitem()
* view_isexpanded()
* view_getcurrenttag()
* view_newitem()
* view_changeviewoptions()
* view_changediffoptions()
* view_findchange()
* view_outline_opt()
* view_freemappings()
* view_findrow()
* view_expand_item()
*
* Comments:
*
* A view owns a COMPLIST, and talks to a table window. The table window
* shows 3 columns: line nr, tag and text. We also need to supply a state
* for each row (used to select colour scheme).
*
* The COMPLIST can give us a list of its COMPITEMs. Each of these can give
* us a tag (eg the filenames compared) and the text (usually the compare
* result), and the state. We make the line number from the
* COMPITEM's place in the list.
*
* If we are asked to switch to 'expand' mode, we ask the selected COMPITEM
* for its composite section list. We can then get the state (and thus
* the tag) from each SECTION, and the line nr and text from the LINEs within
* each section.
*
* When moving between expand and outline, and when refreshing the view
* for some option change, we have to be careful to keep the current row
* and the selected row in the table what the user would expect.
*
* Functions in this module can be called from the UI thread (to refresh
* the display) and simultaneously from a worker thread to update the
* view mapping (view_setcomplist, view_newitem). We use a critical section
* to manage the synchronisation. We need to protect all access/modification
* to the view structure elements (particularly bExpand, rows, pLines and
* pItems), BUT we must not hold the critical section over any calls
* to SendMessage.
*
* We use the global options in windiff.h, and we allocate memory from the
* heap hHeap which has been initialised elsewhere. Points in time-intensive
* loops call Poll() defined elsewhere.
*
****************************************************************************/

#include <windows.h>
#include <stdlib.h>
#include <commdlg.h>

#include "gutils.h"
#include "table.h"
#include "state.h"
#include "windiff.h"
#include "wdiffrc.h"
#include "list.h"
#include "line.h"
#include "scandir.h"
#include "file.h"
#include "section.h"
#include "compitem.h"
#include "complist.h"
#include "view.h"

/*
 * data structures
 */

/* in expand mode, we keep an array of one of these per screen line. */
typedef struct viewline {
        LINE line;              /* handle to LINE for this row */
        SECTION section;        /* handle to section containing this line */
        int nr_left;            /* line nr in left file */
        int nr_right;           /* line nr in right file */
} VIEWLINE, FAR * PVIEWLINE;


/*
 * The users VIEW handle is in fact a pointer to this structure
 */
struct view {

        HWND     hwnd;          /* the table window to send notifies to */

        COMPLIST cl;            /* the complist that we own */

   BOOL          bExpand;       /* true if we are in expand mode */

        COMPITEM ciSelect;      /* selected compitem (in expand mode) */

        int      rows;          /* number of rows in this view */

        char     nrtext[12];    /* we use this in view_gettext for the line
                                 * number column. overwritten on each call
                                 */
        int      maxtag, maxrest;/* column widths in characters for cols 1, 2 */

        /* if we are in outline mode, we map the row number to one entry
         * in this array of COMPITEM handles. this pointer will
         * be NULL in expand mode
         */
        COMPITEM FAR * pItems;

        /* in expand mode we use this array of line and section handles */
        PVIEWLINE pLines;
};


CRITICAL_SECTION CSView;
static BOOL bDoneInit = FALSE;

#define ViewEnter()     EnterCriticalSection(&CSView);
#define ViewLeave()     LeaveCriticalSection(&CSView);

void view_outline_opt(VIEW view, BOOL bRedraw);
void view_freemappings(VIEW view);
int view_findrow(VIEW view, int number, BOOL bRight);
BOOL view_expand_item(VIEW view, COMPITEM ci);


/***************************************************************************
 * Function: view_new
 *
 * Purpose:
 *
 * Create a new view. At this point, we are told the table window handle,
 * and nothing else.
 *
 */
VIEW
view_new(HWND hwndTable)
{
        VIEW view;

        if (!bDoneInit) {
                InitializeCriticalSection(&CSView);
                bDoneInit = TRUE;
        }

        /* alloc the view from the heap */
        view = (VIEW) gmem_get(hHeap, sizeof(struct view));

        /* set the default fields */
        view->hwnd = hwndTable;
        view->cl = NULL;
        view->bExpand = FALSE;
        view->ciSelect = NULL;
        view->rows = 0;
        view->pItems = NULL;
        view->pLines = NULL;

        return(view);
}


/***************************************************************************
 * Function: view_setcomplist
 *
 * Purpose:
 *
 * We have to separate view_new and view_setcomplist because we need
 * to give the view handle to the complist and the complist handle to the
 * view. So do a view_new to create a null view; then complist_new() to
 * which you pass a view handle. The complist will then register itself
 * with the view by calling this function. During the build of the complist,
 * it will also update us by calling view_additem, so that we can refresh
 * the display.
 *
 * Here we should initialise an outline view of the complist.
 *
 * We also talk to the status bar using SetNames to set the names of
 * the two items.
 */
BOOL
view_setcomplist(VIEW view, COMPLIST cl)
{
        LPSTR left, right, both;

        if (view == NULL) {
                return(FALSE);
        }

        /* there can be only one call to this per VIEW */
        if (view->cl != NULL) {
                return (FALSE);
        }

        ViewEnter();

        view->cl = cl;

        /* set names on status bar to root names of left and right trees */
        left = complist_getroot_left(cl);
        right = complist_getroot_right(cl);
        both = gmem_get(hHeap, lstrlen(left) + lstrlen(right) +4);
        wsprintf((LPTSTR)both, "%s : %s", left, right);
        ViewLeave();   
        SetNames(both);
        ViewEnter();   
        gmem_free(hHeap, both, lstrlen(both)+1);
        complist_freeroot_left(cl, left);
        complist_freeroot_right(cl, right);

        ViewLeave();

        view_outline(view);
}


/***************************************************************************
 * Function: view_getcomplist
 *
 * Purpose:
 *
 * Return a handle to the complist owned by this view
 */
COMPLIST
view_getcomplist(VIEW view)
{
        if (view == NULL) {
                return(NULL);
        }

        return(view->cl);
}


/***************************************************************************
 * Function: view_close
 *
 * Purpose:
 *
 * Close a view. Notify the table window that this view should be
 * closed. When the table window has finished with it, it will send
 * a TQ_CLOSE notify that should result in view_delete being called
 * and the memory being freed.
 */
void
view_close(VIEW view)
{
        if (view == NULL) {
                return;
        }

        SendMessage(view->hwnd, TM_NEWID, 0, 0);
}


/***************************************************************************
 * Function: view_delete
 *
 * Purpose:
 *
 * Delete a view and all associated data.
 *
 * This function should only be called in response to the table window
 * sending a TQ_CLOSE message. To close the view, call view_close and
 * wait for the TQ_CLOSE before calling this.
 *
 * We delete the associated COMPLIST and all its associated structures.
 */
void
view_delete(VIEW view)
{
        if (view == NULL) {
                return;
        }

        /* we have two arrays that are used for the mapping - an array
         * of compitem handles in outline mode, and an array of
         * VIEWLINE structures in expand mode
         */

        view_freemappings(view);

        complist_delete(view->cl);

        gmem_free(hHeap, (LPSTR) view, sizeof(struct view));
}


/***************************************************************************
 * Function: view_outline
 *
 * Purpose:
 *
 * Build an outline mode mapping where one row represents one COMPITEM in
 * the list. Check the global option flag outline_include to see which items
 * we should include.
 *
 * If we were in expand mode, then set as the selection the row in outline mode
 * that we were expanding. Also remember to free up the expand mode mapping
 * array
 *
 * Once we have built the new mapping, notify the table window to
 * redraw itself.
 */
void
view_outline(VIEW view)
{
        if (view == NULL) {
                return;
        }

        /* all work done by view_outline_opt - this function
         * gives us the option of not updating the display
         */
        view_outline_opt(view, TRUE);
}



/***************************************************************************
 * Function: view_expand
 *
 * Purpose:
 *
 * Switch to expand mode, expanding the given row into a view
 * of the differences in that file.
 *
 * Map the given row nr into a compitem handle, and then
 * call the internal function with that.
 */
BOOL    
view_expand(VIEW view, long row)
{
        COMPITEM ci;
        BOOL bRet;

        ViewEnter();

        if ((view == NULL) || (view->bExpand)) {
                /* no view, or already expanded */
                ViewLeave();
                return(FALSE);
        }

        if (row >= view->rows) {
                /* no such row */
                ViewLeave();
                return FALSE;
        }

        /* remember the compitem we are expanding */
        ci = view->pItems[row];

        bRet = view_expand_item(view, ci);
        // view_expand_item does the...
        // ViewLeave();
        return(bRet);
}


/***************************************************************************
 * Function: view_gettext
 *
 * Purpose:
 *
 * Return the text associated with a given column of a given row.
 * Return a pointer that does not need to be freed after use - ie
 * a pointer into our data somewhere, not a copy
 */
LPSTR
view_gettext(VIEW view, long row, int col)
{
        int line;
        int state;
        LPSTR pstr;


        if (view == NULL) {
                return (NULL);
        }

        ViewEnter();

        if (row >= view->rows) {
                ViewLeave();
                return(NULL);
        }

        if (view->bExpand) {
                /* we are in expand mode */
                
                state = section_getstate(view->pLines[row].section);

                switch(col) {
                case 0:
                        /* row nr */
                                                
                        /* line numbers can be from either original file
                         * this is a menu-selectable option
                         */
                        switch(line_numbers) {
                        case IDM_NONRS:
                                pstr = NULL;
                                break;

                        case IDM_LNRS:
                                line = view->pLines[row].nr_left;
                                if (state == STATE_MOVEDRIGHT) {
                                        line = -line;
                                }
                                break;

                        case IDM_RNRS:
                                line = view->pLines[row].nr_right;
                                if (state == STATE_MOVEDLEFT) {
                                        line = -line;
                                }
                                break;
                        }
                        if (line == 0) {
                                ViewLeave();
                                return(NULL);
                        }

                        if (line < 0) {
                                /* lines that are moved appear twice.
                                 * show the correct-sequence line nr
                                 * for the out-of-seq. copy in brackets.
                                 */
                                wsprintf((LPTSTR)view->nrtext, "(%d)", abs(line));
                        } else  {
                                wsprintf((LPTSTR)view->nrtext, "%d", line);
                        }
                        pstr = view->nrtext;
                        break;

                case 1:
                        /* tag text - represents the state of the line */


                        switch(state) {
                        case STATE_SAME:
                                pstr = "    ";
                                break;

                        case STATE_LEFTONLY:
                                pstr = " <! ";
                                break;

                        case STATE_RIGHTONLY:
                                pstr = " !> ";
                                break;

                        case STATE_MOVEDLEFT:
                                pstr = " <- ";
                                break;

                        case STATE_MOVEDRIGHT:
                                pstr = " -> ";
                                break;
                        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -