home *** CD-ROM | disk | FTP | other *** search
/ Languages Around the World / LanguageWorld.iso / language / japanese / win_prog / win_jwp / japedit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-31  |  18.7 KB  |  579 lines

  1. /* Copyright (C) Stephen Chung, 1991-1993.  All rights reserved. */
  2.  
  3. #include "jwp.h"
  4. #ifdef CTL3D
  5.     #include <ctl3d.h>
  6. #endif CTL3D
  7.  
  8.  
  9. #define BOXGAP          (AVGHEIGHT / 4)
  10. #define LISTGAP         1
  11. #define LISTLEADING     2
  12.  
  13. extern LONG FAR PASCAL FileWinProc (HWND, WORD, WORD, LONG);
  14.  
  15.  
  16.  
  17.  
  18. void DrawBoundingBox (HWND hwnd, HDC hdc, int control)
  19. {
  20.     RECT rect;
  21.     HWND dlghwnd;
  22.     HBRUSH hbrush;
  23.     HPEN hpen;
  24.  
  25.     dlghwnd = GetDlgItem(hwnd, control),
  26.     GetClientRect(dlghwnd, &rect);
  27.     rect.left = GetWindowWord(dlghwnd, sizeof(FILEOPTIONS *));
  28.     rect.top = GetWindowWord(dlghwnd, sizeof(FILEOPTIONS *) + sizeof(WORD));
  29.  
  30.     hbrush = SelectObject(hdc, CreateSolidBrush(GetSysColor(COLOR_WINDOW)));
  31.     hpen = SelectObject(hdc, CreatePen(PS_SOLID, 1, GetSysColor(COLOR_WINDOWFRAME)));
  32.  
  33.     Rectangle(hdc, rect.left, rect.top, rect.left + rect.right + 2 * BOXGAP,
  34.                    rect.top + rect.bottom + 2 * BOXGAP);
  35.  
  36.     DeleteObject(SelectObject(hdc, hbrush));
  37.     DeleteObject(SelectObject(hdc, hpen));
  38. }
  39.  
  40.  
  41.  
  42. LONG FAR PASCAL JeditProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  43. {
  44.     FILEOPTIONS *f;
  45.  
  46.  
  47.     f = (FILEOPTIONS *) GetWindowWord(hwnd, 0);
  48.  
  49.  
  50.     switch (message) {
  51.         case WM_CREATE: {
  52.             CREATESTRUCT *cp;
  53.             RECT rect;
  54.  
  55.             f = NewFile (FN_CONTROL, TRUE);
  56.             SetWindowWord(hwnd, 0, (WORD) f);
  57.  
  58.             GetClientRect (hwnd, &rect);
  59.             f->hwnd = hwnd;
  60.             f->parent = GetParent(hwnd);
  61.             f->width = rect.right;
  62.             f->height = rect.bottom;
  63.             f->linelen = 1000;
  64.  
  65.             /* Now, we make sure that the window is wide enough */
  66.             cp = (CREATESTRUCT *) lParam;
  67.  
  68.             SetWindowWord(hwnd, sizeof(FILEOPTIONS *), (WORD) cp->x);
  69.             SetWindowWord(hwnd, sizeof(FILEOPTIONS *) + sizeof(WORD), (WORD) cp->y);
  70.             SetWindowWord(hwnd, sizeof(FILEOPTIONS *) + 2 * sizeof(WORD), NULL);
  71.  
  72.             MoveWindow(hwnd, cp->x + BOXGAP, cp->y + BOXGAP,
  73.                         rect.right - 2 * BOXGAP,
  74.                         SYSFONT->height + 2 * LINEGAP(f) + 1, FALSE);
  75.  
  76.             break;
  77.         }
  78.  
  79.         case WM_SIZE:
  80.             f->width = LOWORD(lParam);
  81.             f->height = HIWORD(lParam);
  82.             break;
  83.  
  84.         case EM_GETHANDLE:
  85.             f = (FILEOPTIONS *) GetWindowWord(hwnd, 0);
  86.             return ((LONG) f);
  87.  
  88.         case EM_GETLINE:
  89.             f = (FILEOPTIONS *) GetWindowWord(hwnd, 0);
  90.             return ((LONG) f->paragraph->text);
  91.  
  92.         case EM_SETMODIFY:
  93.             f = (FILEOPTIONS *) GetWindowWord(hwnd, 0);
  94.             f->type = wParam;
  95.             return ((LONG) f);
  96.  
  97.         case EM_SETSEL:
  98.             f = (FILEOPTIONS *) GetWindowWord(hwnd, 0);
  99.             TurnOffSelection(f);
  100.  
  101.             SELPARA1(f) = SELPARA2(f) = f->paragraph;
  102.             SELPOS1(f) = LOWORD(lParam);
  103.             SELPOS2(f) = HIWORD(lParam);
  104.             SELTYPE(f) = SEL_SELECTION;
  105.             FlipHighlight(f);
  106.  
  107.             if (wParam >= 0) {
  108.                 CURCHAR(f) = wParam;
  109.                 if (!FindCaret(f, TRUE)) {
  110.                     MoveIntoWindow(f);
  111.                     InvalidateRect(f->hwnd, NULL, TRUE);
  112.                     UpdateWindow(f->hwnd);
  113.                 }
  114.                 DoCaret(f, CURX(f), CURY(f) - CURLINE(f)->height, TRUE);
  115.             }
  116.             return (0);
  117.  
  118.         case EM_GETSEL:
  119.             f = (FILEOPTIONS *) GetWindowWord(hwnd, 0);
  120.             if (SELPARA1(f) == NULL) return (0);
  121.             return (MAKELONG(SELPOS1(f), SELPOS2(f)));
  122.  
  123.         case EM_SETRECT:
  124.             SetWindowWord(hwnd, sizeof(FILEOPTIONS *) + 2 * sizeof(WORD), wParam);
  125.             return (0);
  126.  
  127.         case WM_GETDLGCODE:
  128.             /* This is an edit control, so we want to process key-strokes * /
  129.             /* by ourselves */
  130.  
  131.             return (DLGC_WANTARROWS | DLGC_WANTALLKEYS | DLGC_WANTCHARS);
  132.  
  133.         case WM_KEYDOWN:
  134.             /* Some of the keys have special meanings */
  135.  
  136.             switch (wParam) {
  137.                 case VK_TAB:
  138.                     if (GetKeyState(VK_SHIFT) < 0)
  139.                         SetFocus(GetNextDlgTabItem(GetParent(hwnd), hwnd, TRUE));
  140.                     else
  141.                         SetFocus(GetNextDlgTabItem(GetParent(hwnd), hwnd, FALSE));
  142.                     return (0);
  143.  
  144.                 case VK_UP:
  145.                 case VK_DOWN:
  146.                 case VK_PRIOR:
  147.                 case VK_NEXT:
  148.                     return (0);
  149.  
  150.                 case VK_RETURN:
  151.                     SendMessage(GetParent(hwnd), WM_COMMAND, IDOK, 0L);
  152.                     return (0);
  153.  
  154.                 case VK_ESCAPE:
  155.                     SendMessage(GetParent(hwnd), WM_COMMAND, IDCANCEL, 0L);
  156.                     return (0);
  157.             }
  158.             break;
  159.  
  160.         case EM_REPLACESEL: {
  161.             KANJI far *cp;
  162.             POSITION p;
  163.             KANJI buf[1] = { 0 };
  164.  
  165.             cp = (KANJI far *) lParam;
  166.  
  167.             PARAOF(p) = f->paragraph;
  168.             LINEOF(p) = f->paragraph->lines;
  169.             POSOF(p) = 0;
  170.  
  171.             TakeCareOfThings(f, TRUE);      /* Get rid of selections */
  172.  
  173.             ReplaceString(f, p, unitlen(f->paragraph->text), (cp != NULL) ? cp : buf,
  174.                             OP_REFORMAT | OP_MOVETOEND | OP_CHOOSEKANJI);
  175.  
  176.             SendMessage(hwnd, WM_KEYDOWN, VK_HOME, 0L);     /* Move to beginning */
  177.             InvalidateRect(hwnd, NULL, TRUE);
  178.             return (TRUE);
  179.         }
  180.  
  181.         case EM_LINELENGTH:
  182.             return (unitlen(f->paragraph->text));
  183.  
  184.         case WM_DESTROY:
  185.             CloseFile(f);
  186.             FreeMem(f);
  187.             SetWindowWord(hwnd, 0, (WORD) NULL);
  188.             return (0);
  189.  
  190.         default:
  191.             break;
  192.     }
  193.  
  194.     if (f == NULL) return (DefWindowProc(hwnd, message, wParam, lParam));
  195.  
  196.     curfile = f;
  197.  
  198.     return (CallWindowProc((FARPROC) FileWinProc, hwnd, message, wParam, lParam));
  199. }
  200.  
  201.  
  202.  
  203. static int KanjiCompare(KANJI far *s1, KANJI far *s2, BOOL KataWithHira, BOOL ASCIIFirst, BOOL SymbolsLast)
  204. {
  205.     KANJI c1, c2;
  206.  
  207.     for (; ; s1++, s2++) {
  208.         c1 = *s1 & 0x7f7f;
  209.         c2 = *s2 & 0x7f7f;
  210.         if (c1 == 0 && c2 == 0) return (0);
  211.  
  212.         else if (c1 == 0) return (-1);
  213.         else if (c2 == 0) return (1);
  214.         else if (c1 == c2) continue;
  215.  
  216.         if (ISKANJI(c1)) {
  217.             if (!ISKANJI(c2)) {
  218.                 if (ASCIIFirst) return (1); else return (-1);
  219.             }
  220.  
  221.             if (SymbolsLast) {
  222.                 if (HIBYTE(c1) < 0x24) c1 += 0x8000;
  223.                 if (HIBYTE(c2) < 0x24) c2 += 0x8000;
  224.             }
  225.  
  226.             switch (HIBYTE(c1)) {
  227.                 case 0x24:
  228.                     switch (HIBYTE(c2)) {
  229.                         case 0x24: return (LOBYTE(c1) - LOBYTE(c2));
  230.                         case 0x25: return (KataWithHira ? (LOBYTE(c1) - LOBYTE(c2)) : -1);
  231.                         default:   return (-1);
  232.                     }
  233.                 case 0x25:
  234.                     switch (HIBYTE(c2)) {
  235.                         case 0x24: return (KataWithHira ? (LOBYTE(c1) - LOBYTE(c2)) : 1);
  236.                         case 0x25: return (LOBYTE(c1) - LOBYTE(c2));
  237.                         default:   return (-1);
  238.                     }
  239.                 default:
  240.                     return (c1 - c2);
  241.             }
  242.         } else {
  243.             if (ISKANJI(c2)) {
  244.                 if (ASCIIFirst) return (-1); else return (1);
  245.             }
  246.  
  247.             if (SymbolsLast) {
  248.                 if (c1 < 'A') c1 += 0x8000;
  249.                 if (c2 < 'A') c2 += 0x8000;
  250.             }
  251.             return (c1 - c2);
  252.         }
  253.     }
  254. }
  255.  
  256.  
  257.  
  258. LONG JlistProc (HWND hwnd, WORD message, WORD wParam, LONG lParam, BOOL select,
  259.                 KANJI far * (* ConvertToString)(int, LONG, KANJI *))
  260. {
  261.     int i, j, k, r;
  262.     char ch;
  263.     COMPAREITEMSTRUCT *comp;
  264.     DELETEITEMSTRUCT *deletep;
  265.     DRAWITEMSTRUCT *drawp;
  266.     MEASUREITEMSTRUCT *measurep;
  267.     KANJI far *cp;
  268.     RECT rect;
  269.     BYTE far *cbufp;
  270.     KANJI buffer[BUFSIZE];
  271.     HBRUSH hbrush;
  272.     HPEN hpen;
  273.  
  274.     switch (message) {
  275.         case WM_COMPAREITEM: {
  276.             KANJI buffer2[BUFSIZE];
  277.             KANJI far *cp2;
  278.  
  279.             comp = (COMPAREITEMSTRUCT *) lParam;
  280.  
  281.             if (ConvertToString != NULL) {
  282.                 cp = ConvertToString(comp->CtlID, comp->itemData1, buffer);
  283.                 cp2 = ConvertToString(comp->CtlID, comp->itemData2, buffer2);
  284.             } else {
  285.                 cp = (KANJI far *) comp->itemData1;
  286.                 cp2 = (KANJI far *) comp->itemData2;
  287.             }
  288.  
  289.             i = KanjiCompare(cp, cp2, TRUE, FALSE, TRUE);
  290.  
  291.             if (i < 0) return (-1);
  292.             else if (i > 0) return (1);
  293.             else return (0);
  294.         }
  295.  
  296.         case WM_DELETEITEM:
  297.             return (TRUE);
  298.  
  299.         case WM_DRAWITEM:
  300.             drawp = (DRAWITEMSTRUCT *) lParam;
  301.  
  302.             if (ConvertToString != NULL) {
  303.                 cp = ConvertToString(drawp->CtlID, drawp->itemData, buffer);
  304.             } else {
  305.                 cp = (KANJI far *) drawp->itemData;
  306.             }
  307.  
  308.             if (select && drawp->itemAction & ODA_FOCUS) {
  309.                 hbrush = SelectObject(drawp->hDC, GetStockObject(NULL_BRUSH));
  310.                 if (drawp->itemState & ODS_FOCUS) {
  311.                     if (drawp->itemState & ODS_SELECTED) {
  312.                         SetBkColor(drawp->hDC, GetSysColor(COLOR_HIGHLIGHT));
  313.                         hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_HIGHLIGHTTEXT));
  314.                     } else {
  315.                         SetBkColor(drawp->hDC, GetSysColor(COLOR_WINDOW));
  316.                         hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_WINDOWTEXT));
  317.                     }
  318.                 } else {
  319.                     if (drawp->itemState & ODS_SELECTED) {
  320.                         SetBkColor(drawp->hDC, GetSysColor(COLOR_HIGHLIGHT));
  321.                         hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_HIGHLIGHT));
  322.                     } else {
  323.                         SetBkColor(drawp->hDC, GetSysColor(COLOR_WINDOW));
  324.                         hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_WINDOW));
  325.                     }
  326.                 }
  327.                 hpen = SelectObject(drawp->hDC, hpen);
  328.                 Rectangle(drawp->hDC, drawp->rcItem.left, drawp->rcItem.top,
  329.                           drawp->rcItem.right, drawp->rcItem.bottom);
  330.  
  331.                 SelectObject(drawp->hDC, hbrush);
  332.                 DeleteObject(SelectObject(drawp->hDC, hpen));
  333.             }
  334.  
  335.             if ((select && drawp->itemAction & ODA_SELECT) || drawp->itemAction & ODA_DRAWENTIRE) {
  336.                 SelectObject(drawp->hDC, NULL_PEN);
  337.  
  338.                 if (drawp->itemState & ODS_SELECTED) {
  339.                     SetTextColor(drawp->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT));
  340.                     SetBkColor(drawp->hDC, GetSysColor(COLOR_HIGHLIGHT));
  341.                     hbrush = CreateSolidBrush(GetSysColor(COLOR_HIGHLIGHT));
  342.                     if (drawp->itemState & ODS_FOCUS) {
  343.                         hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_HIGHLIGHTTEXT));
  344.                         hpen = SelectObject(drawp->hDC, hpen);
  345.                         hbrush = SelectObject(drawp->hDC, hbrush);
  346.                         Rectangle(drawp->hDC, drawp->rcItem.left, drawp->rcItem.top,
  347.                                   drawp->rcItem.right, drawp->rcItem.bottom);
  348.                         DeleteObject(SelectObject(drawp->hDC, hpen));
  349.                         hbrush = SelectObject(drawp->hDC, hbrush);
  350.                     } else {
  351.                         FillRect(drawp->hDC, &(drawp->rcItem), hbrush);
  352.                     }
  353.                 } else {
  354.                     SetTextColor(drawp->hDC, GetSysColor(COLOR_WINDOWTEXT));
  355.                     SetBkColor(drawp->hDC, GetSysColor(COLOR_WINDOW));
  356.                     hbrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  357.                     if (drawp->itemState & ODS_FOCUS) {
  358.                         hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_WINDOWTEXT));
  359.                         hpen = SelectObject(drawp->hDC, hpen);
  360.                         hbrush = SelectObject(drawp->hDC, hbrush);
  361.                         Rectangle(drawp->hDC, drawp->rcItem.left, drawp->rcItem.top,
  362.                                   drawp->rcItem.right, drawp->rcItem.bottom);
  363.                         DeleteObject(SelectObject(drawp->hDC, hpen));
  364.                         hbrush = SelectObject(drawp->hDC, hbrush);
  365.                     } else {
  366.                         FillRect(drawp->hDC, &(drawp->rcItem), hbrush);
  367.                     }
  368.                 }
  369.  
  370.                 DeleteObject(hbrush);
  371.  
  372.                 k = drawp->rcItem.bottom - (BOXGAP / 2);
  373.  
  374.                 for (i = 0, j = drawp->rcItem.left + BOXGAP ; cp[i] != 0; i++) {
  375.                     if (ISKANJI(cp[i])) {
  376.                         r = Jis2Index(cp[i], SYSFONT->holes);
  377.                         if (r < 0) r = Jis2Index(BADKANJI, SYSFONT->holes);
  378.                         r = GetKanjiBitmap(SYSFONT, r, &cbufp);
  379.                         DisplayKanjiBitmap(drawp->hDC, j, k, SYSFONT->width,
  380.                                             SYSFONT->height, r, SRCCOPY, cbufp);
  381.  
  382.                         j += (SYSFONT->width + LISTLEADING);
  383.                     } else if (cp[i] >= ' ') {
  384.                         r = FontCharWidth(cp[i], 0);        /* System font */
  385.  
  386.                         ch = cp[i];
  387.                         TextOut(drawp->hDC, j, k - AVGHEIGHT, &ch, 1);
  388.  
  389.                         j += r;
  390.                         if (cp[i+1] != 0 && ISKANJI(cp[i+1])) j+= LISTLEADING;
  391.                     }
  392.                 }
  393.             }
  394.  
  395.             return (TRUE);
  396.  
  397.         case WM_MEASUREITEM:
  398.             measurep = (MEASUREITEMSTRUCT *) lParam;
  399.  
  400.             GetClientRect(GetDlgItem(hwnd, measurep->CtlID), &rect);
  401.  
  402.             measurep->itemHeight = SYSFONT->height;
  403.             measurep->itemWidth = rect.right;
  404.  
  405.             if (measurep->itemHeight < AVGHEIGHT)
  406.                 measurep->itemHeight = AVGHEIGHT;
  407.  
  408.             measurep->itemHeight += BOXGAP;
  409.  
  410.             return (TRUE);
  411.     }
  412.  
  413.     return (TRUE);
  414. }
  415.  
  416.  
  417.  
  418. LONG FAR PASCAL JtextProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  419. {
  420.     switch (message) {
  421.         case WM_CREATE: {
  422.             RECT rect;
  423.  
  424.             SetWindowWord(hwnd, 0, NULL);
  425.             SetWindowWord(hwnd, sizeof(int), 0);
  426.             SetWindowWord(hwnd, sizeof(KANJI *) + sizeof(int), FALSE);
  427.  
  428.             GetWindowRect(hwnd, &rect);
  429.  
  430.             SetWindowPos(hwnd, NULL, 0, 0, rect.right - rect.left, SYSFONT->height,
  431.                          SWP_NOMOVE | SWP_NOZORDER);
  432.             return (0);
  433.         }
  434.  
  435.         case EM_SETRECT: {
  436.             RECT rect;
  437.             BOOL Box;
  438.  
  439.             Box = (BOOL) GetWindowWord(hwnd, sizeof(KANJI *) + sizeof(int));
  440.             SetWindowWord(hwnd, sizeof(KANJI *) + sizeof(int), wParam);
  441.  
  442.             if ((Box && !wParam) || (!Box && wParam)) {
  443.                 GetWindowRect(hwnd, &rect);
  444.  
  445.                 if (wParam) {
  446.                     SetWindowPos(hwnd, NULL, 0, 0, rect.right - rect.left,
  447.                                  SYSFONT->height + 2 * BOXGAP,
  448.                                  SWP_NOMOVE | SWP_NOZORDER);
  449.                 } else {
  450.                     SetWindowPos(hwnd, NULL, 0, 0, rect.right - rect.left, SYSFONT->height,
  451.                                  SWP_NOMOVE | SWP_NOZORDER);
  452.                 }
  453.                 InvalidateRect(hwnd, NULL, TRUE);
  454.             }
  455.  
  456.             return (0);
  457.         }
  458.  
  459.         case EM_GETLINE:
  460.         case EM_GETHANDLE:
  461.             return ((LONG) GetWindowWord(hwnd, 0));
  462.  
  463.         case EM_REPLACESEL: {
  464.             int i, len;
  465.             KANJI *kp, far *kp1;
  466.  
  467.             kp1 = (KANJI far *) lParam;
  468.             if (kp1 == NULL) kp1 = "";
  469.  
  470.             len = kanjilen(kp1);
  471.  
  472.             kp = (KANJI *) GetWindowWord(hwnd, 0);
  473.  
  474.             i = (len + 5) * sizeof(KANJI);
  475.  
  476.             if (kp == NULL) {
  477.                 kp = (KANJI *) MemAlloc(i);
  478.                 SetWindowWord(hwnd, sizeof(KANJI *), i);
  479.             } else if (GetWindowWord(hwnd, sizeof(KANJI *)) < i) {
  480.                 FreeMem(kp);
  481.                 kp = (KANJI *) MemAlloc(i);
  482.                 SetWindowWord(hwnd, sizeof(KANJI *), i);
  483.             }
  484.             for (i = 0; kp1[i]; i++) kp[i] = kp1[i];
  485.             kp[i] = 0;
  486.  
  487.             SetWindowWord(hwnd, 0, kp);
  488.             return (0);
  489.         }
  490.  
  491.         case WM_PAINT: {
  492.             int i, x, r;
  493.             int offset = 0;
  494.             int ch;
  495.             BYTE far *cbufp;
  496.             KANJI *kp, kch;
  497.             RECT rect;
  498.             HDC hdc;
  499.             PAINTSTRUCT ps;
  500.             extern BOOL Dialogs3D;
  501.  
  502.             hdc = BeginPaint(hwnd, &ps);
  503.  
  504.             SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
  505.  
  506.             if (GetWindowWord(hwnd, sizeof(KANJI *) + sizeof(int))) {
  507.                 /* Draw bounding box */
  508.  
  509.                 offset = BOXGAP;
  510.  
  511.                 GetClientRect(hwnd, &rect);
  512.                 Rectangle(hdc, 0, 0, rect.right, rect.bottom);
  513. #ifdef CTL3D
  514.             } else if (Dialogs3D) {
  515.                 HBRUSH hbrush;
  516.  
  517.                 hbrush = Ctl3dCtlColorEx(WM_CTLCOLOR, hdc, MAKELONG(hwnd, CTLCOLOR_DLG));
  518.                 GetClientRect(hwnd, &rect);
  519.                 FillRect(hdc, &rect, hbrush);
  520. #endif CTL3D
  521.             } else {
  522.                 HBRUSH hbrush;
  523.  
  524.                 hbrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
  525.                 GetClientRect(hwnd, &rect);
  526.                 FillRect(hdc, &rect, hbrush);
  527.                 DeleteObject(hbrush);
  528.             }
  529.  
  530.             kp = (KANJI *) GetWindowWord(hwnd, 0);
  531.             if (kp == NULL) {
  532.                 EndPaint(hwnd, &ps);
  533.                 return (0);
  534.             }
  535.  
  536.             x = 0;
  537.  
  538.             for (i = 0; kp[i]; i++) {
  539.                 kch = kp[i];
  540.  
  541.                 if (ISKANJI(kch)) {
  542.                     if (i > 0 && !ISKANJI(kp[i-1])) x += SYSFONT->leading;
  543.  
  544.                     r = Jis2Index(kch, SYSFONT->holes);
  545.                     if (r < 0) r = Jis2Index(BADKANJI, SYSFONT->holes);
  546.                     r = GetKanjiBitmap(SYSFONT, r, &cbufp);
  547.                     DisplayKanjiBitmap(hdc, x + offset, SYSFONT->height + offset,
  548.                                         SYSFONT->width, SYSFONT->height,
  549.                                         r, SRCAND, cbufp);
  550.                     x += SYSFONT->width + SYSFONT->leading;
  551.                 } else {
  552.                     ch = LOBYTE(kch);
  553.  
  554.                     switch (ch) {
  555.                         case '\t': ch = 0xbb; break;    /* >> symbol */
  556.                         case '\r': ch = 0xb6; break;    /* paragraph symbol */
  557.                         case '\n': ch = 0xab; break;    /* << symbol */
  558.                     }
  559.  
  560.                     TextOut(hdc, x + offset, SYSFONT->height + offset - global.textmetric.tmHeight, &ch, 1);
  561.                     x += FontCharWidth(ch, 0);          /* System font */
  562.                 }
  563.             }
  564.             EndPaint(hwnd, &ps);
  565.             return (0);
  566.         }
  567.  
  568.         case WM_DESTROY: {
  569.             KANJI *kp;
  570.  
  571.             kp = (KANJI *) GetWindowWord(hwnd, 0);
  572.             if (kp != NULL) FreeMem(kp);
  573.             return (0);
  574.         }
  575.     }
  576.  
  577.     return (DefWindowProc(hwnd, message, wParam, lParam));
  578. }
  579.