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

📄 windiff.c

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

        /* search the view for this line nr */
        total = view_getrowcount(current_view);
        for (i = 0; i < total; i++) {
                if (bIsLeft) {
                        if (linenr == view_getlinenr_right(current_view, i)) {
                                /* found it */
                                SetSelection(i);
                                return(TRUE);
                        }
                } else {
                        if (linenr == view_getlinenr_left(current_view, i)) {
                                SetSelection(i);
                                return(TRUE);
                        }
                }
        }
        return(FALSE);
}

/***************************************************************************
 * Function: do_editfile
 *
 * Purpose:
 *
 * Launch an editor on the current file (the file we are expanding, or
 * in outline mode the selected row. Option allows selection of the
 * left file, the right file or the composite view of this item.
 * pe points to a packet of parameters that must be freed before returning.
 * The return value is meaningless (just to conform to CreateThread).
 */
LONG
do_editfile(PEDITARGS pe)
{
        VIEW view = pe->view;
        int option = pe->option;
        int selection = pe->selection;

        COMPITEM item;
        LPSTR fname;
        char cmdline[256];
        int currentline;
        char * pOut = cmdline;
        char * pIn = editor_cmdline;

        STARTUPINFO si;
        PROCESS_INFORMATION pi;

        item = view_getitem(view, selection);
        if (item == NULL) {
                return -1;
        }

        fname = compitem_getfilename(item, option);

        if ( 0 == fname )
        {
            windiff_UI(TRUE);
            MessageBox(hwndClient, LoadRcString(IDS_FILE_DOESNT_EXIST),
                       "Windiff", MB_ICONSTOP|MB_OK);
            windiff_UI(FALSE);
            goto error;
        }

       switch ( option )
        {
        case CI_LEFT:
            currentline = view_getlinenr_left( view,
                                               selection > 0 ? selection : 1);
            break;

        case CI_RIGHT:
            currentline = view_getlinenr_right( view,
                                                selection > 0 ? selection : 1);
            break;

        default:
            currentline = 1;
            break;
        }

        while( *pIn )
        {
            switch( *pIn )
            {
            case '%':
                pIn++;
                switch ( *pIn )
                {
                case 'p':
                    lstrcpy( (LPTSTR)pOut, fname );
                    while ( *pOut )
                        pOut++;
                    break;

                case 'l':
                    _ltoa( currentline, pOut, 10 );
                    while ( *pOut )
                        pOut++;
                    break;

                default:
                    if (IsDBCSLeadByte(*pIn) && *(pIn+1)) {
                        *pOut++ = *pIn++;
                    }
                    *pOut++ = *pIn;
                    break;
                }
                pIn++;
                break;

            default:
                if (IsDBCSLeadByte(*pIn) && *(pIn+1)) {
                    *pOut++ = *pIn++;
                }
                *pOut++ = *pIn++;
                break;
            }
        }


        /* Launch the process and waits for it to complete */

        si.cb = sizeof(STARTUPINFO);
        si.lpReserved = NULL;
        si.lpReserved2 = NULL;
        si.cbReserved2 = 0;
        si.lpTitle = (LPSTR)cmdline; 
        si.lpDesktop = (LPTSTR)NULL;
        si.dwFlags = STARTF_FORCEONFEEDBACK;


        if (!CreateProcess(NULL,
                        cmdline,
                        NULL,
                        NULL,
                        FALSE,
                        NORMAL_PRIORITY_CLASS,
                        NULL,
                        (LPTSTR)NULL,
                        &si,
                        &pi)) {
                windiff_UI(TRUE);
                MessageBox(hwndClient, LoadRcString(IDS_FAILED_TO_LAUNCH_EDT),
                        "Windiff", MB_ICONSTOP|MB_OK);
                windiff_UI(FALSE);
                goto error;
        }

        /* wait for completion. */
        WaitForSingleObject(pi.hProcess, INFINITE);

        /* close process and thread handles */
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);

        /* finished with the filename. deletes it if it was a temp. */
        compitem_freefilename(item, option, fname);

        /*
         * refresh cached view always .  A common trick is to edit the
         * composite file and then save it as a new left or right file.
         * Equally the user can edit the left and save as a new right.
         */

        /* We want to force both files to be re-read, but it's not a terribly
         * good idea to throw the lines away on this thread.  Someone might
         * be reading them on another thread!
         */
        /* file_discardlines(compitem_getleftfile(item)) */
        /* file_discardlines(compitem_getrightfile(item)) */

        /* force the compare to be re-done */
        PostMessage(hwndClient, WM_COMMAND, IDM_UPDATE, (LONG)item);
error:
        gmem_free(hHeap, (LPSTR) pe, sizeof(EDITARGS));

        return 0;

} /* do_editfile */


/***************************************************************************
 * Function: do_editthread
 *
 * Purpose:
 *
 * Launch an editor on a separate thread.  It will actually get a separate
 * process, but we want our own thread in this process.  This thread will
 * wait until it's finished and then order up a refresh of the UI.
 * Need to give it its parameters as a gmem allocated packet because
 * it IS on a separate thread.
 */
void do_editthread(VIEW view, int option)
{
        PEDITARGS pe;
        HANDLE thread;
        DWORD threadid;

        pe = (PEDITARGS) gmem_get(hHeap, sizeof(EDITARGS));
        pe->view = view;
        pe->option = option;
        pe->selection = selection;

        thread = CreateThread( NULL
                             , 0
                             , (LPTHREAD_START_ROUTINE)do_editfile
                             , (LPVOID) pe
                             , 0
                             , &threadid
                             );
        if (thread == NULL)
        {
                /* The createthread failed, do without the extra thread - just
                 * call the function synchronously
                 */
                 do_editfile(pe);
        }
        else CloseHandle(thread);
} /* do_editthread */


/* status bar and busy flags --------------------------------------------*/


/***************************************************************************
 * Function: SetButtonText
 *
 * Purpose:
 *
 * Set the Text on the statusbar button to reflect the current state 
 */
void
SetButtonText(LPSTR cmd)
{
        SendMessage(hwndStatus, SM_SETTEXT, IDM_ABORT, (DWORD) cmd);
}

/***************************************************************************
 * Function: SetStatus
 *
 * Purpose:
 *
 * Set the status field (left-hand part) of the status bar. 
 */
void
SetStatus(LPSTR cmd)
{
        SendMessage(hwndStatus, SM_SETTEXT, IDL_STATLAB, (DWORD) cmd);
}


/***************************************************************************
 * Function: SetNames
 *
 * Purpose:
 *
 * Set the names field - the central box in the status bar 
 */
void
SetNames(LPSTR names)
{
        SendMessage(hwndStatus, SM_SETTEXT, IDL_NAMES, (DWORD) names);
        if (names == NULL) {
                AppTitle[0] = '\0';
        } else {
                strncpy(AppTitle, names, sizeof(AppTitle));
        }
}

/***************************************************************************
 * Function: SetBusy
 *
 * Purpose:
 *
 * If we are not already busy, set the busy flag.
 *
 * Enter critical section first.
 */
BOOL
SetBusy(void)
{
        HMENU hmenu;


        WDEnter();

        if (fBusy) {
                WDLeave();
                return(FALSE);
        }


        fBusy = TRUE;

        SetStatus(LoadRcString(IDS_COMPARING));
        /* status also on window text, so that you can see even from
         * the icon when the scan has finished
         */
        SetWindowText(hwndClient, LoadRcString(IDS_SCANNING));

        /* disable appropriate parts of menu */
        hmenu = GetMenu(hwndClient);
        EnableMenuItem(hmenu, IDM_FILE,MF_DISABLED|MF_GRAYED|MF_BYCOMMAND);
        EnableMenuItem(hmenu, IDM_DIR,MF_DISABLED|MF_GRAYED|MF_BYCOMMAND);
        EnableMenuItem(hmenu, IDM_PRINT,MF_DISABLED|MF_GRAYED|MF_BYCOMMAND);

        /* enable abort only when busy */
        EnableMenuItem(hmenu, IDM_ABORT,MF_ENABLED|MF_BYCOMMAND);
        SetButtonText(LoadRcString(IDS_ABORT));  /* leave DisplayMode unchanged */

        WDLeave();
        return(TRUE);
} /* SetBusy */
/***************************************************************************
 * Function: SetNotBusy
 *
 * Purpose:
 *
 * This function can be called from the worker thread.
 * Thus we must not cause any SendMessage calls to windows
 * owned by the main thread while holding the CritSec or we
 * could cause deadlock.
 *
 * The critsec is only needed to protect the fBusy flag - so
 * clear the busy flag last, and only get the crit sec as needed.
 */
void
SetNotBusy(void)
{
        HMENU hmenu;

        /* reset button and status bar (clearing out busy flags) */
        if (current_view == NULL) {
                SetButtonText(LoadRcString(IDS_EXIT));
                SetStatus(NULL);
                DisplayMode = MODE_NULL;
        } else if (view_isexpanded(current_view)) {
                TCHAR szBuf[10];
                lstrcpy(szBuf,LoadRcString(IDS_OUTLINE));
                SetButtonText(szBuf);
                SetStatus(view_getcurrenttag(current_view) );
                DisplayMode = MODE_EXPAND;
        } else {
                TCHAR szBuf[8];
                lstrcpy(szBuf,LoadRcString(IDS_EXPAND));
                SetButtonText(szBuf);
                SetStatus(NULL);
                DisplayMode = MODE_OUTLINE;
        }

        SetWindowText(hwndClient, "WinDiff");

        /* re-enable appropriate parts of menu */
        hmenu = GetMenu(hwndClient);
        EnableMenuItem(hmenu, IDM_FILE,MF_ENABLED|MF_BYCOMMAND);
        EnableMenuItem(hmenu, IDM_DIR,MF_ENABLED|MF_BYCOMMAND);
        EnableMenuItem(hmenu, IDM_PRINT,MF_ENABLED|MF_BYCOMMAND);

        /* disable abort now no longer busy */
        EnableMenuItem(hmenu, IDM_ABORT,MF_DISABLED|MF_GRAYED|MF_BYCOMMAND);


        /* clear the busy flag, protected by critical section */
        WDEnter();

        fBusy = FALSE;
        bAbort = FALSE;

        if (ghThread!=NULL){
            CloseHandle(ghThread);
            ghThread = NULL;
        }
        WDLeave();
} /* SetNotBusy */

/***************************************************************************
 * Function: IsBusy
 *
 * Purpose:
 *
 * Checks whether or not crit sec is open
 */
BOOL
IsBusy()
{
        BOOL bOK;

        WDEnter();

⌨️ 快捷键说明

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