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

📄 logwin.c

📁 在ecos 下mingui 的移植开发
💻 C
字号:
// $Id: logwin.c,v 1.7 2000/11/17 07:02:01 ymwei Exp $//// logwin.c: implementation file of log window.//// Copyright (c) 2000, WEI Yongming// Copyright (C) 2000, BluePoint Software.//// Current maintainer: WEI Yongming.//// Create date: 2000.xx.xx/***  This library is free software; you can redistribute it and/or**  modify it under the terms of the GNU Library General Public**  License as published by the Free Software Foundation; either**  version 2 of the License, or (at your option) any later version.****  This library is distributed in the hope that it will be useful,**  but WITHOUT ANY WARRANTY; without even the implied warranty of**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU**  Library General Public License for more details.****  You should have received a copy of the GNU Library General Public**  License along with this library; if not, write to the Free**  Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,**  MA 02111-1307, USA*///// Modify records:////  Who             When        Where       For What                Status//-----------------------------------------------------------------------------//// TODO://#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <pthread.h>#include <semaphore.h>#include <sys/stat.h>#include <sys/types.h>#include <unistd.h>#include <errno.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "control.h"#include "logwin.h"typedef struct _LogWinCreateInfo{    HWND     log_win;    sem_t    wait;    BOOL     fVisible;    ONCLOSE  OnClose;    int      nr_rows;    int      nr_cols;    int      max_lines;} LOGWINCREATEINFO;#define MSG_LW_ADDTEXT     (MSG_USER + 1)#define MSG_LW_CLEANUP     (MSG_USER + 2)#define MAX_LENGTH_LINE	    100typedef struct tagTEXTLINE{    int     lineno;    char    text [MAX_LENGTH_LINE + 1];    struct  tagTEXTLINE* next;    struct  tagTEXTLINE* prev;} TEXTLINE;typedef TEXTLINE* PTEXTLINE;typedef struct _LogWinInfo{    int         vis_lines;      // number of visible lines in window    int         max_lines;      // maximal number of lines in window    int         last_line_nr;   // number of last line    PTEXTLINE   lines;          // pointer to text    PTEXTLINE   top_line;       // pointer to first visible line} LOGWININFO;typedef LOGWININFO* PLOGWININFO;#define line_count(info) min (info->max_lines, info->last_line_nr)static void logwinSetVScrollInfo (HWND log_win){    PLOGWININFO info;    SCROLLINFO si;    info = (PLOGWININFO)GetWindowAdditionalData2 (log_win);    if (info->vis_lines >= line_count (info)) {        SetScrollPos (log_win, SB_VERT, 0);        EnableScrollBar (log_win, SB_VERT, FALSE);        return;    }    si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;    si.nMax = line_count (info) - 1;    si.nMin = 0;    si.nPage = min (info->vis_lines, info->last_line_nr - info->top_line->lineno + 1);    si.nPos = info->top_line->lineno - info->lines->lineno;    SetScrollInfo (log_win, SB_VERT, &si, TRUE);    EnableScrollBar (log_win, SB_VERT, TRUE);}static PTEXTLINE next_n_line (PTEXTLINE line, int n){    int i;    for (i = 0; i < n && line; i++) {        line = line->next;    }    return line;}static PTEXTLINE prev_n_line (PTEXTLINE line, int n){    int i;    for (i = 0; i < n && line; i++) {        line = line->prev;    }    return line;}static void logwinOnVScroll (HWND log_win, int scroll_code, int new_pos){    PTEXTLINE top_line;    PLOGWININFO info;    int scroll_height = 0;    int line_height = GetCharHeight ();    int n;    info = (PLOGWININFO) GetWindowAdditionalData2 (log_win);    top_line = info->top_line;    switch (scroll_code) {    case SB_LINEDOWN:        if ((top_line->lineno + info->vis_lines) <= info->last_line_nr) {            top_line = top_line->next;            scroll_height = -line_height;        }        break;                    case SB_LINEUP:        if (top_line->lineno > info->lines->lineno) {            top_line = top_line->prev;            scroll_height = line_height;        }        break;                    case SB_PAGEDOWN:        if ((top_line->lineno + (info->vis_lines << 1)) <= info->last_line_nr)            n = info->vis_lines;        else            n = info->last_line_nr - info->vis_lines - top_line->lineno;        if (n == 0)            return;        top_line = next_n_line (top_line, n);        scroll_height = -(n * line_height);        break;    case SB_PAGEUP:        n = top_line->lineno - info->lines->lineno;        if (n > info->vis_lines)            n = info->vis_lines;        scroll_height = n * line_height;        top_line = prev_n_line (top_line, n);        break;    case SB_THUMBTRACK:        n = new_pos + info->lines->lineno - top_line->lineno;        if (n > 0)            top_line = next_n_line (top_line, n);        else if (n < 0)            top_line = prev_n_line (top_line, -n);        else            return;        scroll_height = -(n * line_height);        break;    }                if (scroll_height) {        info->top_line = top_line;        ScrollWindow (log_win, 0, scroll_height, NULL, NULL);        SendMessage (log_win, MSG_PAINT, 0, 0);        logwinSetVScrollInfo (log_win);        return;    }}static BOOL logwinAddTextLine (HWND log_win, const char* text, BOOL fUpdate){    PLOGWININFO info;    PTEXTLINE line;    PTEXTLINE oldline = NULL;    int nCharH = GetCharHeight ();    int top_lineno = 1;    PTEXTLINE top_next = NULL;    info = (PLOGWININFO)GetWindowAdditionalData2 (log_win);    if (info->last_line_nr >= info->max_lines) {        oldline = info->lines;        info->lines = info->lines->next;    }        if (!info->lines) {        if (oldline)            info->lines  = oldline;        else            info->lines = malloc (sizeof (TEXTLINE));        if (info->lines == NULL) {            info->lines = oldline;            return FALSE;        }        line = info->lines;        line->prev = NULL;    }    else {        line = info->lines;        while (line->next) {            line = line->next;        }                if (oldline)            line->next = oldline;        else            line->next = malloc (sizeof (TEXTLINE));        if (line->next == NULL) {            return FALSE;        }        line->next->prev = line;        line = line->next;    }    if (info->top_line) {        top_lineno = info->top_line->lineno;        top_next   = info->top_line->next;    }    strncpy (line->text, text, MAX_LENGTH_LINE);    line->text [MAX_LENGTH_LINE] = '\0';    line->next = NULL;    line->lineno = ++info->last_line_nr;    if (info->last_line_nr == 1)        info->top_line = info->lines;    if (fUpdate) {        RECT rcLine;        RECT rcClient;                if (info->last_line_nr >= (top_lineno + info->vis_lines)) {            info->top_line = top_next;            ScrollWindow (log_win, 0, -nCharH, NULL, NULL);            SendMessage (log_win, MSG_PAINT, 0, 0);        }        else {            // Get line output rect            GetClientRect (log_win, &rcClient);            rcLine.left   = rcClient.left;            rcLine.right  = rcClient.right;            rcLine.top    = rcClient.top + nCharH * (info->last_line_nr - top_lineno);            rcLine.bottom = rcLine.top + nCharH;                    InvalidateRect (log_win, &rcLine, FALSE);            SendMessage (log_win, MSG_PAINT, 0, 0);        }    }    logwinSetVScrollInfo (log_win);    return TRUE;}static void logwinDeleteContent (HWND log_win){    PLOGWININFO info;    PTEXTLINE line;    PTEXTLINE next;    info = (PLOGWININFO)GetWindowAdditionalData2 (log_win);    line = info->lines;    if (!line) return;    while (line) {        next = line->next;        free (line);        line = next;    }    info->lines = NULL;    info->last_line_nr = 0;}static void logwinOutLogWinText(HWND log_win, HDC hdc){    PLOGWININFO info;    PTEXTLINE line;    RECT rcClient;    RECT rcLine;    int iLine = 0;    int nCharH = GetCharHeight ();    info = (PLOGWININFO)GetWindowAdditionalData2 (log_win);    line = info->top_line;        GetClientRect (log_win, &rcClient);    SetTextColor (hdc, COLOR_lightwhite);    SetBkColor (hdc, COLOR_black);    while (line) {        char szLineNo [10];        rcLine.left = rcClient.left + 2;        rcLine.top = rcClient.top + nCharH*iLine;        rcLine.right = rcClient.right;        rcLine.bottom = rcLine.top + nCharH;                sprintf (szLineNo, "%06d", line->lineno);        TextOut (hdc, rcLine.left, rcLine.top, szLineNo);        TextOut (hdc, rcLine.left + GetCharWidth () * 6 + 4,                          rcLine.top, line->text);                line = line->next;        iLine++;    }}static int LogWinProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam){    switch (message) {    case MSG_CREATE:        EnableScrollBar (hWnd, SB_VERT, FALSE);        break;    case MSG_PAINT:    {        HDC hdc;        hdc = BeginPaint (hWnd);        logwinOutLogWinText(hWnd, hdc);        EndPaint (hWnd, hdc);    }    return 0;    case MSG_LW_ADDTEXT:        logwinAddTextLine (hWnd, (char*)lParam, TRUE);        break;    case MSG_LW_CLEANUP:        logwinDeleteContent (hWnd);        break;    case MSG_VSCROLL:        logwinOnVScroll (hWnd, (int)wParam, (int)lParam);        break;    case MSG_CLOSE:    {        ONCLOSE OnClose = (ONCLOSE) GetWindowAdditionalData (hWnd);        if (!OnClose || (*OnClose) (hWnd)) {            logwinDeleteContent (hWnd);            DestroyMainWindow (hWnd);            PostQuitMessage (hWnd);        }        break;    } // case    } // switch     return DefaultMainWinProc(hWnd, message, wParam, lParam);}static void logwinInitCreateInfo (PMAINWINCREATE pCreateInfo, int rows, int cols){    pCreateInfo->dwStyle = WS_THINFRAME | WS_VSCROLL | WS_CAPTION;    pCreateInfo->dwExStyle = WS_EX_NOCLOSEBOX;    pCreateInfo->spCaption = "Log Window";    pCreateInfo->hMenu = 0;    pCreateInfo->hCursor = GetSystemCursor(0);    pCreateInfo->hIcon = 0;    pCreateInfo->MainWindowProc = LogWinProc;    pCreateInfo->lx = 0;    pCreateInfo->ty = GetGDCapability (HDC_SCREEN, GDCAP_MAXY) - GetCharHeight () * rows - 1;    pCreateInfo->rx = pCreateInfo->lx + GetCharWidth () * cols + 2;    pCreateInfo->rx += GetMainWinMetrics (MWM_CXVSCROLL);    pCreateInfo->by = GetGDCapability (HDC_SCREEN, GDCAP_MAXY) + 1;    pCreateInfo->ty -= GetMainWinMetrics (MWM_CAPTIONY);    pCreateInfo->iBkColor = COLOR_black;    pCreateInfo->dwAddData = 0;    pCreateInfo->hHosting = HWND_DESKTOP;} static void* LogWindow (void* data){    MSG Msg;    MAINWINCREATE CreateInfo;    HWND hMainWnd;    LOGWINCREATEINFO* LogWinCreateInfo = (LOGWINCREATEINFO*)data;    LOGWININFO info;    RECT rcClient;    if (LogWinCreateInfo->nr_rows <= 0)        LogWinCreateInfo->nr_rows = 1;    if (LogWinCreateInfo->nr_cols <= 0)        LogWinCreateInfo->nr_cols = 1;    logwinInitCreateInfo (&CreateInfo,             LogWinCreateInfo->nr_rows, LogWinCreateInfo->nr_cols);    if (LogWinCreateInfo->fVisible)        CreateInfo.dwStyle |= WS_VISIBLE;    CreateInfo.dwAddData = (DWORD)(LogWinCreateInfo->OnClose);    hMainWnd = CreateMainWindow (&CreateInfo);    LogWinCreateInfo->log_win = hMainWnd;    info.vis_lines  = LogWinCreateInfo->nr_rows;    info.max_lines  = (LogWinCreateInfo->max_lines > LogWinCreateInfo->nr_rows) ?                         LogWinCreateInfo->max_lines : LogWinCreateInfo->nr_rows;    info.last_line_nr  = 0;    info.lines   = NULL;    info.top_line= NULL;    sem_post (&LogWinCreateInfo->wait);    if (hMainWnd == HWND_INVALID)        return NULL;    GetClientRect (hMainWnd, &rcClient);    SetWindowAdditionalData2 (hMainWnd, (DWORD)(&info));    while( GetMessage (&Msg, hMainWnd) ) {        DispatchMessage (&Msg);    }    MainWindowThreadCleanup (hMainWnd);    return NULL;}HWND CreateLogWin (BOOL fVisible, ONCLOSE OnClose, int nr_rows, int nr_cols, int max_lines){    LOGWINCREATEINFO LogWinCreateInfo;    pthread_t th;    if (nr_rows < 3 || nr_cols < 3)        return HWND_INVALID;    sem_init (&LogWinCreateInfo.wait, 0, 0);    LogWinCreateInfo.fVisible = fVisible;    LogWinCreateInfo.OnClose  = OnClose;    LogWinCreateInfo.nr_rows  = nr_rows;    LogWinCreateInfo.nr_cols  = nr_cols;    LogWinCreateInfo.max_lines = max_lines;    CreateThreadForMainWindow (&th, NULL, LogWindow, &LogWinCreateInfo);    sem_wait (&LogWinCreateInfo.wait);    sem_destroy (&LogWinCreateInfo.wait);    return LogWinCreateInfo.log_win;} void DestroyLogWin (HWND log_win){    SendMessage (log_win, MSG_CLOSE, 0, 0);}void LogMessage (HWND log_win, const char* format, ...){    char text [MAX_LENGTH_LINE + 1];    va_list args;    va_start (args, format);    vsnprintf (text, MAX_LENGTH_LINE, format, args);    va_end (args);    SendMessage (log_win, MSG_LW_ADDTEXT, 0, (LPARAM)text);}int IsLogWinVisible (HWND log_win){    if (log_win == HWND_INVALID)        return -1;    if (IsWindowVisible (log_win))        return 1;    return 0;}void ToggleLogWin (HWND log_win){    switch (IsLogWinVisible (log_win)) {    case 0:        ShowWindow (log_win, SW_SHOW);        break;    case 1:        ShowWindow (log_win, SW_HIDE);        break;    }}void DumpAllLogMessages (HWND log_win, FILE* fp){    PLOGWININFO info;    PTEXTLINE line;    info = (PLOGWININFO)GetWindowAdditionalData2 (log_win);    line = info->lines;    while (line) {        fprintf (fp, "%s\n", line->text);        line = line->next;    }}

⌨️ 快捷键说明

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