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

📄 windiff.c

📁 <Win2k系统编程>源码.次数为国人自编,内容丰富,还是不错的.
💻 C
📖 第 1 页 / 共 5 页
字号:


/****************************** Module Header *******************************
* Module Name: WINDIFF.C
*
* File and directory comparisions.
*
* Functions:
*
* windiff_UI()
* WinMain()
* windiff_usage()
* Poll()
* DoResize()
* AboutBox()
* DoPrint()
* FindNextChange()
* FindPrevChange()
* WriteProfileInt()
* ToOutline()
* ToMoved()
* do_editfile()
* do_editthread()
* SetStatus()
* SetNames()
* IsBusy()
* BusyError()
* StateToColour()
* SetSelection()
* do_gethdr()
* do_getprops()
* do_getdata()
* SvrClose()
* TableServer()
* wd_dirdialog()
* wd_copy()
* InitApplication()
* InitInstance()
* CreateTools()
* DeleteTools()
* MainWndProc()
* SetBusy()
* SetNotBusy()
* SetSelection()
* SetButtonText()
* ToExpand()
* ParseArgs()
* wd_initial()
*
* Comments:
*
* Compare two directories (including all files and subdirs). Look for names
* that are present in both (report all that are not). For files that
* are present in both, produce a line-by-line comparison of the differences
* between the two files (if any).
*
* Overview of Windiff internals - the whole program.
*
* Windiff is built from several modules (a "module" has a .h file
* which describes its interface and a .c file which implements it).
* Apart from THIS comment which tries to give an overview of the whole
* scheme of things, each module is as self-contained as possible.
* This is enforced by the use of opaque data types.  Modules cannot
* see each others' internal data structures.  Modules are abstract
* data types.  The term "Module" (from Modula2) and "Class" (from C++)
* are used synonymously.
*
*    Windiff  - main program - parse arguments, put up main window,
*               handle input, calling other modules as needed
*               invoke table class to create the main display and
*               service callbacks from the table class.
*               Contains global flags for options (e.g. ignore_blanks)
*    list     - (in gutils) a generalised LIST of anything data type
*               has full set of operations for insert, delete, join etc.
*    line     - a LINE is a numbered line of text.  Information is kept to
*               allow fast comparisons of LINEs.  A LINE can hold a
*               link to another LINE.  The links are used to connect
*               lines in one file to matching lines in the other file.
*    file     - a FILEDATA represents a file as a file name in the form
*               of a DIRITEM and a LIST of LINEs
*    scandir  - a DIRITEM represents information about a file.  (for
*               instance its name, whether it has a local copy).
*    compitem - a COMPITEM is a pair of files together with information
*               on how they compare in the form of a breakdown of the
*               files into a LIST of matching or non-matching sections.
*               Either file can be absent.  This module contains the
*               file "contrast" algorithm used for the actual comparison
*    tree       (in gutils) A binary tree.  Important because it is what
*               gives the file comparison its speed as it makes it
*               an "N log N" algorithm rather than "N squared"
*    complist - a COMPLIST is the master data structure.  It has a DIRLIST
*               of the left hand files, a DIRLIST of the right hand files
*               and a LIST of COMPITEMs. The left and right hand DIRLISTs
*               are working data used to produce the COMPLIST.  The LIST
*               is displayed as the outline table.  Any given COMPITEM can
*               be displayed as an expanded item.
*    section  - a SECTION is a section of a file (first line, last line)
*               and information as to what it matches in the other file.
*    bar.c    - the picture down the left of the screen
*               has a WNDPROC.  
*    view     - Although the COMPLIST is the master state, it doesn't do
*               all the work itself.  The data is actually displayed by
*               the table class which is highly generalised.  View
*               owns a COMPLIST (and therefore calls upon the functions
*               in complist to fill it and interrogate it) and calls
*               upon (and is called back by) the functions in table to
*               actually display it.  Read about table in gutils.h
*    table.c    (in gutils) a highly generalised system for displaying
*               data in rows and columns.  The interface is in gutils.h.
*    status.c   (in gutils) the status line at the top. See gutils.h
*************************************************************************
*
* Overview of this file:
*
*   We create a table window (gutils.dll) to show the files and the
*   results of their comparisons. We create a COMPLIST object representing
*   a list of files and their differences, and a VIEW object to map between
*   the rows of the table window and the COMPLIST.
*
*   This module is responsible for creating and managing the main window,
*   placing the child windows (table, status window etc) within it, and
*   handling all menu items. We maintain global option flags set by
*   menu commands.
*
*   Creating a COMPLIST creates a list of unmatched files, and of matching
*   files that are compared with each other (these are COMPITEMS).
*   The VIEW provides a mapping between rows on the screen, and items in
*   the COMPLIST.
*
*   This version tries to maintain a responsive user interface by
*   creating worker threads to do long jobs.  This potentially creates
*   conflicts between the threads as they will both want to update common
*   variables (for instance the UI thread may be changing the options to
*   exclude identical files while the worker thread is adding in the
*   results of new comparisons).  Critical sections are used to manage
*   the conflicts.
*
*   The Edit options invoke an editor on a separate thread.  This allows
*   us to repaint our window and thereby allow the user to refer back to
*   what he saw before invoking the editor.  When he's finished editing,
*   we would of course like to refresh things and if this is still on the
*   separate thread it might clash. We avoid this clash by POSTing ourselves
*   a (WM_COMMAND, IDM_UPDATE) message.
*
****************************************************************************/

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

#include "gutils.h"
#include "table.h"
#include "list.h"
#include "scandir.h"            /* needed for file.h     */
#include "file.h"               /* needed for compitem.h */
#include "compitem.h"           /* needed for view.h     */
#include "complist.h"
#include "view.h"
#include "state.h"
#include "windiff.h"
#include "wdiffrc.h"


/*--constants and data types--------------------------------------------*/

int Version = 2;
int SubVersion = 01;

/* When we print the current table, we pass this id as the table id
 * When we are queried for the properties of this table, we know they
 * want the printing properties for the current view. We use this to
 * select different fonts and colours for the printer.
 */
#define TABID_PRINTER   1



/*
 * structure containing args passed to worker thread in initial
 * case (executing command line instructions). 
 */
typedef struct {

        LPSTR first;
        LPSTR second;
        LPSTR savelist;
        UINT saveopts;
        VIEW view;
        BOOL fDeep;
} THREADARGS, FAR * PTHREADARGS;


/* Structure containing all the arguments we'd like to give to do_editfile
   Need a structure because CreateThread only allows for one argument.
*/
typedef struct {
        VIEW view;
        int option;
        int selection;
} EDITARGS, FAR * PEDITARGS;

/*---- colour scheme------------------------------- */

/* outline */
DWORD rgb_outlinehi = RGB(255, 0, 0);   /* hilighted files in outline mode  */

/* expand view */
DWORD rgb_leftfore =   RGB(  0,   0,   0);         /* foregrnd for left lines */
DWORD rgb_leftback  =  RGB(255,   0,   0);         /* backgrnd for left lines */
DWORD rgb_rightfore =  RGB(  0,   0,   0);         /* foregrnd for right lines*/
DWORD rgb_rightback =  RGB(255, 255,   0);         /* backgrnd for right lines*/

/* moved lines */
DWORD rgb_mleftfore =  RGB(  0,   0, 128);         /* foregrnd for moved-left */
DWORD rgb_mleftback =  RGB(255,   0,   0);         /* backgrnd for moved-left */
DWORD rgb_mrightfore = RGB(  0,   0, 255);         /* foregrnd for moved-right*/
DWORD rgb_mrightback = RGB(255, 255,   0);         /* backgrnd for moved-right*/

/* bar window */
DWORD rgb_barleft =    RGB(255,   0,   0);         /* bar sections in left only  */
DWORD rgb_barright =   RGB(255, 255,   0);         /* bar sections in right only */
DWORD rgb_barcurrent = RGB(  0,   0, 255);         /* current pos markers in bar */


/* module static data -------------------------------------------------*/


/* current value of window title */
char AppTitle[256];


HWND hwndClient;        /* main window */
HWND hwndRCD;           /* table window */
HWND hwndStatus;        /* status bar across top */
HWND hwndBar;           /* graphic of sections as vertical bars */

HACCEL haccel;

/* The status bar told us it should be this high. Rest of client area
 * goes to the hwndBar and hwndRCD.
 */
int status_height;

HINSTANCE hInst;   /* handle to current app instance */
HMENU hMenu;    /* handle to menu for hwndClient */

int nMinMax = SW_SHOWNORMAL;         /* default state of window normal */

/* The message sent to us as a callback by the table window needs to be
 * registered - table_msgcode is the result of the RegisterMessage call
 */
UINT table_msgcode;

/* True if we are currently doing some scan or comparison.
 * Must get critical section before checking/changing this (call
 * SetBusy.
 */
BOOL fBusy = FALSE;

int     selection       =       -1;     /* selected row in table*/

/* Options for DisplayMode field indicating what is currently shown.
 * We use this to know whether or not to show the graphic bar window.
 */
#define MODE_NULL       0       /* nothing displayed */
#define MODE_OUTLINE    1       /* a list of files displayed */
#define MODE_EXPAND     2       /* view is expanded view of one file */

int DisplayMode = MODE_NULL;    /* indicates whether we are in expand mode */

VIEW current_view = NULL;

/* command line parameters */
extern int __argc;
extern char ** __argv;

BOOL bAbort = FALSE;    /* set to request abort of current operation */

char editor_cmdline[256] = "notepad %p";  /* editor cmdline */
                          /* slick version is "s %p -#%l" */

/* app-wide global data --------------------------------------------- */

/* Handle returned from gmem_init - we use this for all memory allocations */
HANDLE hHeap;

/* Current state of menu options */
int line_numbers = IDM_LNRS;
int expand_mode = IDM_BOTHFILES;
int outline_include = INCLUDE_LEFTONLY|INCLUDE_RIGHTONLY|INCLUDE_SAME|INCLUDE_DIFFER;
BOOL ignore_blanks = TRUE;
BOOL picture_mode = TRUE;

/* function prototypes ---------------------------------------------*/

BOOL InitApplication(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow);
void CreateTools(void);
void DeleteTools(void);
long APIENTRY MainWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam);
BOOL SetBusy(void);
void SetNotBusy(void);
void SetSelection(long rownr);
void SetButtonText(LPSTR cmd);
BOOL ToExpand(HWND hwnd);
void ParseArgs(int argc, char ** argv);


DWORD wd_initial(LPVOID arg);

static HANDLE ghThread = NULL;

static DWORD gdwMainThreadId;     /* threadid of main (user interface) thread
                                     initialised in winmain(), thereafter constant.
                                     See windiff_UI()
                                  */

/***************************************************************************
 * Function: windiff_UI
 *
 * Purpose:
 *
 * If you are about to put up a dialog box or in fact process input in any way
 * on any thread other than the main thread - or if you MIGHT be on a thread other
 * than the main thread, then you must call this function with TRUE before doing
 * it and with FALSE immediately afterwards.  Otherwise you will get one of a
 * number of flavours of not-very-responsiveness
 */
void windiff_UI(BOOL bAttach)
{
        DWORD dwThreadId = GetCurrentThreadId();
        if (dwThreadId==gdwMainThreadId) return;

        if (bAttach) GetDesktopWindow();
        AttachThreadInput(dwThreadId, gdwMainThreadId, bAttach);
} /* windiff_UI */

/***************************************************************************
 * Function: WinMain
 *
 * Purpose:
 *
 * Main entry point. Register window classes, create windows,
 * parse command line arguments and then perform a message loop
 */
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

        MSG msg;

        gdwMainThreadId = GetCurrentThreadId();

        /* create any pens/brushes etc and read in profile defaults */
        CreateTools();

        /* init window class unless other instances running */
        if (!hPrevInstance)
            if (!InitApplication(hInstance))
                return(FALSE);


        /* init this instance - create all the windows */
        if (!InitInstance(hInstance, nCmdShow))
            return(FALSE);

        ParseArgs(__argc, __argv);


        /* message loop */
        while(GetMessage(&msg, NULL, 0, 0)) {
                if (!TranslateAccelerator(hwndClient, haccel, &msg)) {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }
        }

        return (msg.wParam);

}

/***************************************************************************
 * Function: InitApplication
 *
 * Purpose:
 *
 * Register window class for the main window and the bar window.

⌨️ 快捷键说明

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