TTY.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:62k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /******************************************************************************
  2. *       This is a part of the Microsoft Source Code Samples.
  3. *       Copyright (C) 1993-1997 Microsoft Corporation.
  4. *       All rights reserved.
  5. *       This source code is only intended as a supplement to
  6. *       Microsoft Development Tools and/or WinHelp documentation.
  7. *       See these sources for detailed information regarding the
  8. *       Microsoft samples programs.
  9. ******************************************************************************/
  10. //---------------------------------------------------------------------------
  11. //
  12. //  Module: tty.c
  13. //
  14. //  Purpose:
  15. //     The sample application demonstrates the usage of the COMM
  16. //     API.  It implements the new COMM API of Windows 3.1.
  17. //
  18. //     NOTE:  no escape sequences are translated, only
  19. //            the necessary control codes (LF, CR, BS, etc.)
  20. //
  21. //  Description of functions:
  22. //     Descriptions are contained in the function headers.
  23. //
  24. //---------------------------------------------------------------------------
  25. //
  26. //  Written by Microsoft Product Support Services, Windows Developer Support.
  27. //
  28. //---------------------------------------------------------------------------
  29. #include "tty.h"
  30. //---------------------------------------------------------------------------
  31. //  int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance,
  32. //                      LPSTR lpszCmdLine, int nCmdShow )
  33. //
  34. //  Description:
  35. //     This is the main window loop!
  36. //
  37. //  Parameters:
  38. //     As documented for all WinMain() functions.
  39. //
  40. //---------------------------------------------------------------------------
  41. int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  42.                     LPSTR lpszCmdLine, int nCmdShow )
  43. {
  44.    MSG   msg ;
  45.    if (!hPrevInstance)
  46.       if (!InitApplication( hInstance ))
  47.          return ( FALSE ) ;
  48.    if (NULL == (hTTYWnd = InitInstance( hInstance, nCmdShow )))
  49.       return ( FALSE ) ;
  50.    while (GetMessage( &msg, NULL, 0, 0 ))
  51.    {
  52.       if (!TranslateAccelerator( hTTYWnd, ghAccel, &msg ))
  53.       {
  54.          TranslateMessage( &msg ) ;
  55.          DispatchMessage( &msg ) ;
  56.       }
  57.    }
  58.    return ( (int) msg.wParam ) ;
  59. } // end of WinMain()
  60. //---------------------------------------------------------------------------
  61. //  BOOL NEAR InitApplication( HANDLE hInstance )
  62. //
  63. //  Description:
  64. //     First time initialization stuff.  This registers information
  65. //     such as window classes.
  66. //
  67. //  Parameters:
  68. //     HANDLE hInstance
  69. //        Handle to this instance of the application.
  70. //
  71. //---------------------------------------------------------------------------
  72. BOOL NEAR InitApplication( HANDLE hInstance )
  73. {
  74.    WNDCLASS  wndclass ;
  75.    // register tty window class
  76.    wndclass.style =         0 ;
  77.    wndclass.lpfnWndProc =   TTYWndProc ;
  78.    wndclass.cbClsExtra =    0 ;
  79.    wndclass.cbWndExtra =    TTYEXTRABYTES ;
  80.    wndclass.hInstance =     hInstance ;
  81.    wndclass.hIcon =         LoadIcon( hInstance, MAKEINTRESOURCE( TTYICON ) );
  82.    wndclass.hCursor =       LoadCursor( NULL, IDC_ARROW ) ;
  83.    wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1) ;
  84.    wndclass.lpszMenuName =  MAKEINTRESOURCE( TTYMENU ) ;
  85.    wndclass.lpszClassName = gszTTYClass ;
  86.    return( RegisterClass( &wndclass ) ) ;
  87. } // end of InitApplication()
  88. //---------------------------------------------------------------------------
  89. //  HWND NEAR InitInstance( HANDLE hInstance, int nCmdShow )
  90. //
  91. //  Description:
  92. //     Initializes instance specific information.
  93. //
  94. //  Parameters:
  95. //     HANDLE hInstance
  96. //        Handle to instance
  97. //
  98. //     int nCmdShow
  99. //        How do we show the window?
  100. //
  101. //---------------------------------------------------------------------------
  102. HWND NEAR InitInstance( HANDLE hInstance, int nCmdShow )
  103. {
  104.    HWND  hTTYWnd ;
  105.    // load accelerators
  106.    ghAccel = LoadAccelerators( hInstance, MAKEINTRESOURCE( TTYACCEL ) ) ;
  107.    // create the TTY window
  108.    hTTYWnd = CreateWindow( gszTTYClass, gszAppName,
  109.                            WS_OVERLAPPEDWINDOW,
  110.                            CW_USEDEFAULT, CW_USEDEFAULT,
  111.                            CW_USEDEFAULT, CW_USEDEFAULT,
  112.                            NULL, NULL, hInstance, NULL ) ;
  113.    if (NULL == hTTYWnd)
  114.       return ( NULL ) ;
  115.    ShowWindow( hTTYWnd, nCmdShow ) ;
  116.    UpdateWindow( hTTYWnd ) ;
  117.    return ( hTTYWnd ) ;
  118. } // end of InitInstance()
  119. //---------------------------------------------------------------------------
  120. //  LRESULT FAR PASCAL TTYWndProc( HWND hWnd, UINT uMsg,
  121. //                                 WPARAM wParam, LPARAM lParam )
  122. //
  123. //  Description:
  124. //     This is the TTY Window Proc.  This handles ALL messages
  125. //     to the tty window.
  126. //
  127. //  Parameters:
  128. //     As documented for Window procedures.
  129. //
  130. //  Win-32 Porting Issues:
  131. //     - WM_HSCROLL and WM_VSCROLL packing is different under Win-32.
  132. //     - Needed LOWORD() of wParam for WM_CHAR messages.
  133. //
  134. //---------------------------------------------------------------------------
  135. LRESULT FAR PASCAL TTYWndProc( HWND hWnd, UINT uMsg,
  136.                                WPARAM wParam, LPARAM lParam )
  137. {
  138.    DWORD dwBlockSize=512;
  139.    char * szBuffer;
  140.    switch (uMsg)
  141.    {
  142.       case WM_CREATE:
  143.          return ( CreateTTYInfo( hWnd ) ) ;
  144.       case WM_COMMAND:
  145.       {
  146.          switch ( LOWORD( wParam ) )
  147.          {
  148.             case IDM_CONNECT:
  149.                if (!OpenConnection( hWnd ))
  150.                   MessageBox( hWnd, "Connection failed.", gszAppName,
  151.                               MB_ICONEXCLAMATION ) ;
  152.                break ;
  153.             case IDM_DISCONNECT:
  154.                KillTTYFocus( hWnd ) ;
  155.                CloseConnection( hWnd ) ;
  156.                break ;
  157.             case IDM_SETTINGS:
  158.             {
  159.                NPTTYINFO  npTTYInfo ;
  160.                if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  161.                   return ( FALSE ) ;
  162.                GoModalDialogBoxParam( GETHINST( hWnd ),
  163.                                       MAKEINTRESOURCE( SETTINGSDLGBOX ), hWnd,
  164.                                       (DLGPROC) SettingsDlgProc,
  165.                                       (LPARAM) (LPSTR) npTTYInfo ) ;
  166.                // if fConnected, set new COM parameters
  167.                if (CONNECTED( npTTYInfo ))
  168.                {
  169.                   if (!SetupConnection( hWnd ))
  170.                      MessageBox( hWnd, "Settings failed!", gszAppName,
  171.                                  MB_ICONEXCLAMATION ) ;
  172.                }
  173.             }
  174.             break ;
  175.             case IDM_SENDBLOCK:
  176.                // This function is very useful to test how
  177.                // your comm application handles large blocks
  178.                // of data
  179.                szBuffer = malloc(dwBlockSize);
  180.                memset(szBuffer, 'X', dwBlockSize);
  181.                WriteCommBlock( hWnd, szBuffer, dwBlockSize);
  182.                free(szBuffer);
  183.                break;
  184.             case IDM_ABOUT:
  185.                GoModalDialogBoxParam ( GETHINST( hWnd ),
  186.                                        MAKEINTRESOURCE( ABOUTDLGBOX ),
  187.                                        hWnd,
  188.                                        (DLGPROC) AboutDlgProc, 0L ) ;
  189.                break;
  190.             case IDM_EXIT:
  191.                PostMessage( hWnd, WM_CLOSE, 0, 0L ) ;
  192.                break ;
  193.          }
  194.       }
  195.       break ;
  196.       case WM_PAINT:
  197.          PaintTTY( hWnd ) ;
  198.          break ;
  199.       case WM_SIZE:
  200.          SizeTTY( hWnd, HIWORD( lParam ), LOWORD( lParam ) ) ;
  201.          break ;
  202.       case WM_HSCROLL:
  203.          ScrollTTYHorz( hWnd, LOWORD( wParam ), HIWORD( wParam ) ) ;
  204.          break ;
  205.       case WM_VSCROLL:
  206.          ScrollTTYVert( hWnd, LOWORD( wParam ), HIWORD( wParam ) ) ;
  207.          break ;
  208.       case WM_CHAR:
  209.          ProcessTTYCharacter( hWnd, LOBYTE( LOWORD( wParam ) ) ) ;
  210.          break ;
  211.       case WM_SETFOCUS:
  212.          SetTTYFocus( hWnd ) ;
  213.          break ;
  214.       case WM_KILLFOCUS:
  215.          KillTTYFocus( hWnd ) ;
  216.          break ;
  217.       case WM_DESTROY:
  218.          DestroyTTYInfo( hWnd ) ;
  219.          PostQuitMessage( 0 ) ;
  220.          break ;
  221.       case WM_CLOSE:
  222.          if (IDOK != MessageBox( hWnd, "OK to close window?", "TTY Sample",
  223.                                  MB_ICONQUESTION | MB_OKCANCEL ))
  224.             break ;
  225.          // fall through
  226.       default:
  227.          return( DefWindowProc( hWnd, uMsg, wParam, lParam ) ) ;
  228.    }
  229.    return 0L ;
  230. } // end of TTYWndProc()
  231. //---------------------------------------------------------------------------
  232. //  LRESULT NEAR CreateTTYInfo( HWND hWnd )
  233. //
  234. //  Description:
  235. //     Creates the tty information structure and sets
  236. //     menu option availability.  Returns -1 if unsuccessful.
  237. //
  238. //  Parameters:
  239. //     HWND  hWnd
  240. //        Handle to main window.
  241. //
  242. //  Win-32 Porting Issues:
  243. //     - Needed to initialize TERMWND( npTTYInfo ) for secondary thread.
  244. //     - Needed to create/initialize overlapped structures used in reads &
  245. //       writes to COMM device.
  246. //
  247. //---------------------------------------------------------------------------
  248. LRESULT NEAR CreateTTYInfo( HWND hWnd )
  249. {
  250.    HMENU       hMenu ;
  251.    NPTTYINFO   npTTYInfo ;
  252.    if (NULL == (npTTYInfo =
  253.                    (NPTTYINFO) LocalAlloc( LPTR, sizeof( TTYINFO ) )))
  254.       return ( (LRESULT) -1 ) ;
  255.    // initialize TTY info structure
  256.    COMDEV( npTTYInfo )        = 0 ;
  257.    CONNECTED( npTTYInfo )     = FALSE ;
  258.    CURSORSTATE( npTTYInfo )   = CS_HIDE ;
  259.    LOCALECHO( npTTYInfo )     = FALSE ;
  260.    AUTOWRAP( npTTYInfo )      = TRUE ;
  261.    PORT( npTTYInfo )          = 1 ;
  262.    BAUDRATE( npTTYInfo )      = CBR_9600 ;
  263.    BYTESIZE( npTTYInfo )      = 8 ;
  264.    //FLOWCTRL( npTTYInfo )      = FC_RTSCTS ;
  265.    FLOWCTRL( npTTYInfo )      = FC_XONXOFF ;
  266.    PARITY( npTTYInfo )        = NOPARITY ;
  267.    STOPBITS( npTTYInfo )      = ONESTOPBIT ;
  268.    XONXOFF( npTTYInfo )       = FALSE ;
  269.    XSIZE( npTTYInfo )         = 0 ;
  270.    YSIZE( npTTYInfo )         = 0 ;
  271.    XSCROLL( npTTYInfo )       = 0 ;
  272.    YSCROLL( npTTYInfo )       = 0 ;
  273.    XOFFSET( npTTYInfo )       = 0 ;
  274.    YOFFSET( npTTYInfo )       = 0 ;
  275.    COLUMN( npTTYInfo )        = 0 ;
  276.    ROW( npTTYInfo )           = 0 ;
  277.    HTTYFONT( npTTYInfo )      = NULL ;
  278.    FGCOLOR( npTTYInfo )       = RGB( 0, 0, 0 ) ;
  279.    USECNRECEIVE( npTTYInfo )  = TRUE ;
  280.    DISPLAYERRORS( npTTYInfo ) = TRUE ;
  281.    WRITE_OS( npTTYInfo ).Offset = 0 ;
  282.    WRITE_OS( npTTYInfo ).OffsetHigh = 0 ;
  283.    READ_OS( npTTYInfo ).Offset = 0 ;
  284.    READ_OS( npTTYInfo ).OffsetHigh = 0 ;
  285.    TERMWND( npTTYInfo ) =       hWnd ;
  286.    // create I/O event used for overlapped reads / writes
  287.    READ_OS( npTTYInfo ).hEvent = CreateEvent( NULL,    // no security
  288.                                               TRUE,    // explicit reset req
  289.                                               FALSE,   // initial event reset
  290.                                               NULL ) ; // no name
  291.    if (READ_OS( npTTYInfo ).hEvent == NULL)
  292.    {
  293.       LocalFree( npTTYInfo ) ;
  294.       return ( -1 ) ;
  295.    }
  296.    WRITE_OS( npTTYInfo ).hEvent = CreateEvent( NULL,    // no security
  297.                                                TRUE,    // explicit reset req
  298.                                                FALSE,   // initial event reset
  299.                                                NULL ) ; // no name
  300.    if (NULL == WRITE_OS( npTTYInfo ).hEvent)
  301.    {
  302.       CloseHandle( READ_OS( npTTYInfo ).hEvent ) ;
  303.       LocalFree( npTTYInfo ) ;
  304.       return ( -1 ) ;
  305.    }
  306.    // clear screen space
  307.    _fmemset( SCREEN( npTTYInfo ), ' ', MAXROWS * MAXCOLS ) ;
  308.    // setup default font information
  309.    LFTTYFONT( npTTYInfo ).lfHeight =         9 ;
  310.    LFTTYFONT( npTTYInfo ).lfWidth =          0 ;
  311.    LFTTYFONT( npTTYInfo ).lfEscapement =     0 ;
  312.    LFTTYFONT( npTTYInfo ).lfOrientation =    0 ;
  313.    LFTTYFONT( npTTYInfo ).lfWeight =         0 ;
  314.    LFTTYFONT( npTTYInfo ).lfItalic =         0 ;
  315.    LFTTYFONT( npTTYInfo ).lfUnderline =      0 ;
  316.    LFTTYFONT( npTTYInfo ).lfStrikeOut =      0 ;
  317.    LFTTYFONT( npTTYInfo ).lfCharSet =        OEM_CHARSET ;
  318.    LFTTYFONT( npTTYInfo ).lfOutPrecision =   OUT_DEFAULT_PRECIS ;
  319.    LFTTYFONT( npTTYInfo ).lfClipPrecision =  CLIP_DEFAULT_PRECIS ;
  320.    LFTTYFONT( npTTYInfo ).lfQuality =        DEFAULT_QUALITY ;
  321.    LFTTYFONT( npTTYInfo ).lfPitchAndFamily = FIXED_PITCH | FF_MODERN ;
  322.    lstrcpy( LFTTYFONT( npTTYInfo ).lfFaceName, "FixedSys" ) ;
  323.    // set TTYInfo handle before any further message processing.
  324.    SETNPTTYINFO( hWnd, npTTYInfo ) ;
  325.    // reset the character information, etc.
  326.    ResetTTYScreen( hWnd, npTTYInfo ) ;
  327.    hMenu = GetMenu( hWnd ) ;
  328.    EnableMenuItem( hMenu, IDM_DISCONNECT,
  329.                    MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ) ;
  330.    EnableMenuItem( hMenu, IDM_CONNECT, MF_ENABLED | MF_BYCOMMAND ) ;
  331.    return ( (LRESULT) TRUE ) ;
  332. } // end of CreateTTYInfo()
  333. //---------------------------------------------------------------------------
  334. //  BOOL NEAR DestroyTTYInfo( HWND hWnd )
  335. //
  336. //  Description:
  337. //     Destroys block associated with TTY window handle.
  338. //
  339. //  Parameters:
  340. //     HWND hWnd
  341. //        handle to TTY window
  342. //
  343. //  Win-32 Porting Issues:
  344. //     - Needed to clean up event objects created during initialization.
  345. //
  346. //---------------------------------------------------------------------------
  347. BOOL NEAR DestroyTTYInfo( HWND hWnd )
  348. {
  349.    NPTTYINFO npTTYInfo ;
  350.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  351.       return ( FALSE ) ;
  352.    // force connection closed (if not already closed)
  353.    if (CONNECTED( npTTYInfo ))
  354.       CloseConnection( hWnd ) ;
  355.    // clean up event objects
  356.    CloseHandle( READ_OS( npTTYInfo ).hEvent ) ;
  357.    CloseHandle( WRITE_OS( npTTYInfo ).hEvent ) ;
  358.    CloseHandle( POSTEVENT( npTTYInfo ) ) ;
  359.    DeleteObject( HTTYFONT( npTTYInfo ) ) ;
  360.    LocalFree( npTTYInfo ) ;
  361.    return ( TRUE ) ;
  362. } // end of DestroyTTYInfo()
  363. //---------------------------------------------------------------------------
  364. //  BOOL NEAR ResetTTYScreen( HWND hWnd, NPTTYINFO npTTYInfo )
  365. //
  366. //  Description:
  367. //     Resets the TTY character information and causes the
  368. //     screen to resize to update the scroll information.
  369. //
  370. //  Parameters:
  371. //     NPTTYINFO  npTTYInfo
  372. //        pointer to TTY info structure
  373. //
  374. //---------------------------------------------------------------------------
  375. BOOL NEAR ResetTTYScreen( HWND hWnd, NPTTYINFO npTTYInfo )
  376. {
  377.    HDC         hDC ;
  378.    TEXTMETRIC  tm ;
  379.    RECT        rcWindow ;
  380.    if (NULL == npTTYInfo)
  381.       return ( FALSE ) ;
  382.    if (NULL != HTTYFONT( npTTYInfo ))
  383.       DeleteObject( HTTYFONT( npTTYInfo ) ) ;
  384.    HTTYFONT( npTTYInfo ) = CreateFontIndirect( &LFTTYFONT( npTTYInfo ) ) ;
  385.    hDC = GetDC( hWnd ) ;
  386.    SelectObject( hDC, HTTYFONT( npTTYInfo ) ) ;
  387.    GetTextMetrics( hDC, &tm ) ;
  388.    ReleaseDC( hWnd, hDC ) ;
  389.    XCHAR( npTTYInfo ) = tm.tmAveCharWidth  ;
  390.    YCHAR( npTTYInfo ) = tm.tmHeight + tm.tmExternalLeading ;
  391.    // a slimy hack to force the scroll position, region to
  392.    // be recalculated based on the new character sizes
  393.    GetWindowRect( hWnd, &rcWindow ) ;
  394.    SendMessage( hWnd, WM_SIZE, SIZENORMAL,
  395.                 (LPARAM) MAKELONG( rcWindow.right - rcWindow.left,
  396.                                    rcWindow.bottom - rcWindow.top ) ) ;
  397.    return ( TRUE ) ;
  398. } // end of ResetTTYScreen()
  399. //---------------------------------------------------------------------------
  400. //  BOOL NEAR PaintTTY( HWND hWnd )
  401. //
  402. //  Description:
  403. //     Paints the rectangle determined by the paint struct of
  404. //     the DC.
  405. //
  406. //  Parameters:
  407. //     HWND hWnd
  408. //        handle to TTY window (as always)
  409. //
  410. //---------------------------------------------------------------------------
  411. BOOL NEAR PaintTTY( HWND hWnd )
  412. {
  413.    int          nRow, nCol, nEndRow, nEndCol, nCount, nHorzPos, nVertPos ;
  414.    HDC          hDC ;
  415.    HFONT        hOldFont ;
  416.    NPTTYINFO    npTTYInfo ;
  417.    PAINTSTRUCT  ps ;
  418.    RECT         rect ;
  419.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  420.       return ( FALSE ) ;
  421.    hDC = BeginPaint( hWnd, &ps ) ;
  422.    hOldFont = SelectObject( hDC, HTTYFONT( npTTYInfo ) ) ;
  423.    SetTextColor( hDC, FGCOLOR( npTTYInfo ) ) ;
  424.    SetBkColor( hDC, GetSysColor( COLOR_WINDOW ) ) ;
  425.    rect = ps.rcPaint ;
  426.    nRow =
  427.       min( MAXROWS - 1,
  428.            max( 0, (rect.top + YOFFSET( npTTYInfo )) / YCHAR( npTTYInfo ) ) ) ;
  429.    nEndRow =
  430.       min( MAXROWS - 1,
  431.            ((rect.bottom + YOFFSET( npTTYInfo ) - 1) / YCHAR( npTTYInfo ) ) ) ;
  432.    nCol =
  433.       min( MAXCOLS - 1,
  434.            max( 0, (rect.left + XOFFSET( npTTYInfo )) / XCHAR( npTTYInfo ) ) ) ;
  435.    nEndCol =
  436.       min( MAXCOLS - 1,
  437.            ((rect.right + XOFFSET( npTTYInfo ) - 1) / XCHAR( npTTYInfo ) ) ) ;
  438.    nCount = nEndCol - nCol + 1 ;
  439.    for (; nRow <= nEndRow; nRow++)
  440.    {
  441.       nVertPos = (nRow * YCHAR( npTTYInfo )) - YOFFSET( npTTYInfo ) ;
  442.       nHorzPos = (nCol * XCHAR( npTTYInfo )) - XOFFSET( npTTYInfo ) ;
  443.       rect.top = nVertPos ;
  444.       rect.bottom = nVertPos + YCHAR( npTTYInfo ) ;
  445.       rect.left = nHorzPos ;
  446.       rect.right = nHorzPos + XCHAR( npTTYInfo ) * nCount ;
  447.       SetBkMode( hDC, OPAQUE ) ;
  448.       ExtTextOut( hDC, nHorzPos, nVertPos, ETO_OPAQUE | ETO_CLIPPED, &rect,
  449.                   (LPSTR)( SCREEN( npTTYInfo ) + nRow * MAXCOLS + nCol ),
  450.                   nCount, NULL ) ;
  451.    }
  452.    SelectObject( hDC, hOldFont ) ;
  453.    EndPaint( hWnd, &ps ) ;
  454.    MoveTTYCursor( hWnd ) ;
  455.    return ( TRUE ) ;
  456. } // end of PaintTTY()
  457. //---------------------------------------------------------------------------
  458. //  BOOL NEAR SizeTTY( HWND hWnd, WORD wVertSize, WORD wHorzSize )
  459. //
  460. //  Description:
  461. //     Sizes TTY and sets up scrolling regions.
  462. //
  463. //  Parameters:
  464. //     HWND hWnd
  465. //        handle to TTY window
  466. //
  467. //     WORD wVertSize
  468. //        new vertical size
  469. //
  470. //     WORD wHorzSize
  471. //        new horizontal size
  472. //
  473. //---------------------------------------------------------------------------
  474. BOOL NEAR SizeTTY( HWND hWnd, WORD wVertSize, WORD wHorzSize )
  475. {
  476.    int        nScrollAmt ;
  477.    NPTTYINFO  npTTYInfo ;
  478.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  479.       return ( FALSE ) ;
  480.    YSIZE( npTTYInfo ) = (int) wVertSize ;
  481.    YSCROLL( npTTYInfo ) = max( 0, (MAXROWS * YCHAR( npTTYInfo )) -
  482.                                YSIZE( npTTYInfo ) ) ;
  483.    nScrollAmt = min( YSCROLL( npTTYInfo ), YOFFSET( npTTYInfo ) ) -
  484.                      YOFFSET( npTTYInfo ) ;
  485.    ScrollWindow( hWnd, 0, -nScrollAmt, NULL, NULL ) ;
  486.    YOFFSET( npTTYInfo ) = YOFFSET( npTTYInfo ) + nScrollAmt ;
  487.    SetScrollPos( hWnd, SB_VERT, YOFFSET( npTTYInfo ), FALSE ) ;
  488.    SetScrollRange( hWnd, SB_VERT, 0, YSCROLL( npTTYInfo ), TRUE ) ;
  489.    XSIZE( npTTYInfo ) = (int) wHorzSize ;
  490.    XSCROLL( npTTYInfo ) = max( 0, (MAXCOLS * XCHAR( npTTYInfo )) -
  491.                                 XSIZE( npTTYInfo ) ) ;
  492.    nScrollAmt = min( XSCROLL( npTTYInfo ), XOFFSET( npTTYInfo )) -
  493.                      XOFFSET( npTTYInfo ) ;
  494.    ScrollWindow( hWnd, 0, -nScrollAmt, NULL, NULL ) ;
  495.    XOFFSET( npTTYInfo ) = XOFFSET( npTTYInfo ) + nScrollAmt ;
  496.    SetScrollPos( hWnd, SB_HORZ, XOFFSET( npTTYInfo ), FALSE ) ;
  497.    SetScrollRange( hWnd, SB_HORZ, 0, XSCROLL( npTTYInfo ), TRUE ) ;
  498.    InvalidateRect( hWnd, NULL, TRUE ) ;
  499.    return ( TRUE ) ;
  500. } // end of SizeTTY()
  501. //---------------------------------------------------------------------------
  502. //  BOOL NEAR ScrollTTYVert( HWND hWnd, WORD wScrollCmd, WORD wScrollPos )
  503. //
  504. //  Description:
  505. //     Scrolls TTY window vertically.
  506. //
  507. //  Parameters:
  508. //     HWND hWnd
  509. //        handle to TTY window
  510. //
  511. //     WORD wScrollCmd
  512. //        type of scrolling we're doing
  513. //
  514. //     WORD wScrollPos
  515. //        scroll position
  516. //
  517. //---------------------------------------------------------------------------
  518. BOOL NEAR ScrollTTYVert( HWND hWnd, WORD wScrollCmd, WORD wScrollPos )
  519. {
  520.    int        nScrollAmt ;
  521.    NPTTYINFO  npTTYInfo ;
  522.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  523.       return ( FALSE ) ;
  524.    switch (wScrollCmd)
  525.    {
  526.       case SB_TOP:
  527.          nScrollAmt = -YOFFSET( npTTYInfo ) ;
  528.          break ;
  529.       case SB_BOTTOM:
  530.          nScrollAmt = YSCROLL( npTTYInfo ) - YOFFSET( npTTYInfo ) ;
  531.          break ;
  532.       case SB_PAGEUP:
  533.          nScrollAmt = -YSIZE( npTTYInfo ) ;
  534.          break ;
  535.       case SB_PAGEDOWN:
  536.          nScrollAmt = YSIZE( npTTYInfo ) ;
  537.          break ;
  538.       case SB_LINEUP:
  539.          nScrollAmt = -YCHAR( npTTYInfo ) ;
  540.          break ;
  541.       case SB_LINEDOWN:
  542.          nScrollAmt = YCHAR( npTTYInfo ) ;
  543.          break ;
  544.       case SB_THUMBPOSITION:
  545.          nScrollAmt = wScrollPos - YOFFSET( npTTYInfo ) ;
  546.          break ;
  547.       default:
  548.          return ( FALSE ) ;
  549.    }
  550.    if ((YOFFSET( npTTYInfo ) + nScrollAmt) > YSCROLL( npTTYInfo ))
  551.       nScrollAmt = YSCROLL( npTTYInfo ) - YOFFSET( npTTYInfo ) ;
  552.    if ((YOFFSET( npTTYInfo ) + nScrollAmt) < 0)
  553.       nScrollAmt = -YOFFSET( npTTYInfo ) ;
  554.    ScrollWindow( hWnd, 0, -nScrollAmt, NULL, NULL ) ;
  555.    YOFFSET( npTTYInfo ) = YOFFSET( npTTYInfo ) + nScrollAmt ;
  556.    SetScrollPos( hWnd, SB_VERT, YOFFSET( npTTYInfo ), TRUE ) ;
  557.    return ( TRUE ) ;
  558. } // end of ScrollTTYVert()
  559. //---------------------------------------------------------------------------
  560. //  BOOL NEAR ScrollTTYHorz( HWND hWnd, WORD wScrollCmd, WORD wScrollPos )
  561. //
  562. //  Description:
  563. //     Scrolls TTY window horizontally.
  564. //
  565. //  Parameters:
  566. //     HWND hWnd
  567. //        handle to TTY window
  568. //
  569. //     WORD wScrollCmd
  570. //        type of scrolling we're doing
  571. //
  572. //     WORD wScrollPos
  573. //        scroll position
  574. //
  575. //---------------------------------------------------------------------------
  576. BOOL NEAR ScrollTTYHorz( HWND hWnd, WORD wScrollCmd, WORD wScrollPos )
  577. {
  578.    int        nScrollAmt ;
  579.    NPTTYINFO  npTTYInfo ;
  580.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  581.       return ( FALSE ) ;
  582.    switch (wScrollCmd)
  583.    {
  584.       case SB_TOP:
  585.          nScrollAmt = -XOFFSET( npTTYInfo ) ;
  586.          break ;
  587.       case SB_BOTTOM:
  588.          nScrollAmt = XSCROLL( npTTYInfo ) - XOFFSET( npTTYInfo ) ;
  589.          break ;
  590.       case SB_PAGEUP:
  591.          nScrollAmt = -XSIZE( npTTYInfo ) ;
  592.          break ;
  593.       case SB_PAGEDOWN:
  594.          nScrollAmt = XSIZE( npTTYInfo ) ;
  595.          break ;
  596.       case SB_LINEUP:
  597.          nScrollAmt = -XCHAR( npTTYInfo ) ;
  598.          break ;
  599.       case SB_LINEDOWN:
  600.          nScrollAmt = XCHAR( npTTYInfo ) ;
  601.          break ;
  602.       case SB_THUMBPOSITION:
  603.          nScrollAmt = wScrollPos - XOFFSET( npTTYInfo ) ;
  604.          break ;
  605.       default:
  606.          return ( FALSE ) ;
  607.    }
  608.    if ((XOFFSET( npTTYInfo ) + nScrollAmt) > XSCROLL( npTTYInfo ))
  609.       nScrollAmt = XSCROLL( npTTYInfo ) - XOFFSET( npTTYInfo ) ;
  610.    if ((XOFFSET( npTTYInfo ) + nScrollAmt) < 0)
  611.       nScrollAmt = -XOFFSET( npTTYInfo ) ;
  612.    ScrollWindow( hWnd, -nScrollAmt, 0, NULL, NULL ) ;
  613.    XOFFSET( npTTYInfo ) = XOFFSET( npTTYInfo ) + nScrollAmt ;
  614.    SetScrollPos( hWnd, SB_HORZ, XOFFSET( npTTYInfo ), TRUE ) ;
  615.    return ( TRUE ) ;
  616. } // end of ScrollTTYHorz()
  617. //---------------------------------------------------------------------------
  618. //  BOOL NEAR SetTTYFocus( HWND hWnd )
  619. //
  620. //  Description:
  621. //     Sets the focus to the TTY window also creates caret.
  622. //
  623. //  Parameters:
  624. //     HWND hWnd
  625. //        handle to TTY window
  626. //
  627. //---------------------------------------------------------------------------
  628. BOOL NEAR SetTTYFocus( HWND hWnd )
  629. {
  630.    NPTTYINFO  npTTYInfo ;
  631.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  632.       return ( FALSE ) ;
  633.    if (CONNECTED( npTTYInfo ) && (CURSORSTATE( npTTYInfo ) != CS_SHOW))
  634.    {
  635.       CreateCaret( hWnd, NULL, XCHAR( npTTYInfo ), YCHAR( npTTYInfo ) ) ;
  636.       ShowCaret( hWnd ) ;
  637.       CURSORSTATE( npTTYInfo ) = CS_SHOW ;
  638.    }
  639.    MoveTTYCursor( hWnd ) ;
  640.    return ( TRUE ) ;
  641. } // end of SetTTYFocus()
  642. //---------------------------------------------------------------------------
  643. //  BOOL NEAR KillTTYFocus( HWND hWnd )
  644. //
  645. //  Description:
  646. //     Kills TTY focus and destroys the caret.
  647. //
  648. //  Parameters:
  649. //     HWND hWnd
  650. //        handle to TTY window
  651. //
  652. //---------------------------------------------------------------------------
  653. BOOL NEAR KillTTYFocus( HWND hWnd )
  654. {
  655.    NPTTYINFO  npTTYInfo ;
  656.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  657.       return ( FALSE ) ;
  658.    if (CONNECTED( npTTYInfo ) && (CURSORSTATE( npTTYInfo ) != CS_HIDE))
  659.    {
  660.       HideCaret( hWnd ) ;
  661.       DestroyCaret() ;
  662.       CURSORSTATE( npTTYInfo ) = CS_HIDE ;
  663.    }
  664.    return ( TRUE ) ;
  665. } // end of KillTTYFocus()
  666. //---------------------------------------------------------------------------
  667. //  BOOL NEAR MoveTTYCursor( HWND hWnd )
  668. //
  669. //  Description:
  670. //     Moves caret to current position.
  671. //
  672. //  Parameters:
  673. //     HWND hWnd
  674. //        handle to TTY window
  675. //
  676. //---------------------------------------------------------------------------
  677. BOOL NEAR MoveTTYCursor( HWND hWnd )
  678. {
  679.    NPTTYINFO  npTTYInfo ;
  680.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  681.       return ( FALSE ) ;
  682.    if (CONNECTED( npTTYInfo ) && (CURSORSTATE( npTTYInfo ) & CS_SHOW))
  683.       SetCaretPos( (COLUMN( npTTYInfo ) * XCHAR( npTTYInfo )) -
  684.                    XOFFSET( npTTYInfo ),
  685.                    (ROW( npTTYInfo ) * YCHAR( npTTYInfo )) -
  686.                    YOFFSET( npTTYInfo ) ) ;
  687.    return ( TRUE ) ;
  688. } // end of MoveTTYCursor()
  689. //---------------------------------------------------------------------------
  690. //  BOOL NEAR ProcessTTYCharacter( HWND hWnd, BYTE bOut )
  691. //
  692. //  Description:
  693. //     This simply writes a character to the port and echos it
  694. //     to the TTY screen if fLocalEcho is set.  Some minor
  695. //     keyboard mapping could be performed here.
  696. //
  697. //  Parameters:
  698. //     HWND hWnd
  699. //        handle to TTY window
  700. //
  701. //     BYTE bOut
  702. //        byte from keyboard
  703. //
  704. //---------------------------------------------------------------------------
  705. BOOL NEAR ProcessTTYCharacter( HWND hWnd, BYTE bOut )
  706. {
  707.    NPTTYINFO  npTTYInfo ;
  708.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  709.       return ( FALSE ) ;
  710.    if (!CONNECTED( npTTYInfo ))
  711.       return ( FALSE ) ;
  712.    // a robust app would take appropriate steps if WriteCommBlock failed
  713.    WriteCommBlock( hWnd, &bOut, 1 ) ;
  714.    if (LOCALECHO( npTTYInfo ))
  715.       WriteTTYBlock( hWnd, &bOut, 1 ) ;
  716.    return ( TRUE ) ;
  717. } // end of ProcessTTYCharacter()
  718. //---------------------------------------------------------------------------
  719. //  BOOL NEAR OpenConnection( HWND hWnd )
  720. //
  721. //  Description:
  722. //     Opens communication port specified in the TTYINFO struct.
  723. //     It also sets the CommState and notifies the window via
  724. //     the fConnected flag in the TTYINFO struct.
  725. //
  726. //  Parameters:
  727. //     HWND hWnd
  728. //        handle to TTY window
  729. //
  730. //  Win-32 Porting Issues:
  731. //     - OpenComm() is not supported under Win-32.  Use CreateFile()
  732. //       and setup for OVERLAPPED_IO.
  733. //     - Win-32 has specific communication timeout parameters.
  734. //     - Created the secondary thread for event notification.
  735. //
  736. //---------------------------------------------------------------------------
  737. BOOL NEAR OpenConnection( HWND hWnd )
  738. {
  739.    char       szPort[ 15 ], szTemp[ 10 ] ;
  740.    BOOL       fRetVal ;
  741.    HCURSOR    hOldCursor, hWaitCursor ;
  742.    HMENU      hMenu ;
  743.    NPTTYINFO  npTTYInfo ;
  744.    HANDLE        hCommWatchThread ;
  745.    DWORD         dwThreadID ;
  746.    COMMTIMEOUTS  CommTimeOuts ;
  747.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  748.       return ( FALSE ) ;
  749.    // show the hourglass cursor
  750.    hWaitCursor = LoadCursor( NULL, IDC_WAIT ) ;
  751.    hOldCursor = SetCursor( hWaitCursor ) ;
  752.    // load the COM prefix string and append port number
  753.    LoadString( GETHINST( hWnd ), IDS_COMPREFIX, szTemp, sizeof( szTemp ) ) ;
  754.    wsprintf( szPort, "%s%d", (LPSTR) szTemp, PORT( npTTYInfo ) ) ;
  755.    // open COMM device
  756.    if ((COMDEV( npTTYInfo ) =
  757.       CreateFile( szPort, GENERIC_READ | GENERIC_WRITE,
  758.                   0,                    // exclusive access
  759.                   NULL,                 // no security attrs
  760.                   OPEN_EXISTING,
  761.                   FILE_ATTRIBUTE_NORMAL |
  762.                   FILE_FLAG_OVERLAPPED, // overlapped I/O
  763.                   NULL )) == (HANDLE) -1 )
  764.       return ( FALSE ) ;
  765.    else
  766.    {
  767.       // get any early notifications
  768.       SetCommMask( COMDEV( npTTYInfo ), EV_RXCHAR ) ;
  769.       // setup device buffers
  770.       SetupComm( COMDEV( npTTYInfo ), 4096, 4096 ) ;
  771.       // purge any information in the buffer
  772.       PurgeComm( COMDEV( npTTYInfo ), PURGE_TXABORT | PURGE_RXABORT |
  773.                                       PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
  774.       // set up for overlapped I/O
  775.       CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF ;
  776.       CommTimeOuts.ReadTotalTimeoutMultiplier = 0 ;
  777.       CommTimeOuts.ReadTotalTimeoutConstant = 1000 ;
  778.       // CBR_9600 is approximately 1byte/ms. For our purposes, allow
  779.       // double the expected time per character for a fudge factor.
  780.       CommTimeOuts.WriteTotalTimeoutMultiplier = 2*CBR_9600/BAUDRATE( npTTYInfo ) ;
  781.       CommTimeOuts.WriteTotalTimeoutConstant = 0 ;
  782.       SetCommTimeouts( COMDEV( npTTYInfo ), &CommTimeOuts ) ;
  783.    }
  784.    fRetVal = SetupConnection( hWnd ) ;
  785.    if (fRetVal)
  786.    {
  787.       CONNECTED( npTTYInfo ) = TRUE ;
  788.       // Create a secondary thread
  789.       // to watch for an event.
  790.       if (NULL == (hCommWatchThread =
  791.                       CreateThread( (LPSECURITY_ATTRIBUTES) NULL,
  792.                                     0,
  793.                                     (LPTHREAD_START_ROUTINE) CommWatchProc,
  794.                                     (LPVOID) npTTYInfo,
  795.                                     0, &dwThreadID )))
  796.       {
  797.          CONNECTED( npTTYInfo ) = FALSE ;
  798.          CloseHandle( COMDEV( npTTYInfo ) ) ;
  799.          fRetVal = FALSE ;
  800.       }
  801.       else
  802.       {
  803.          THREADID( npTTYInfo ) = dwThreadID ;
  804.          HTHREAD( npTTYInfo ) = hCommWatchThread ;
  805.          // assert DTR
  806.          EscapeCommFunction( COMDEV( npTTYInfo ), SETDTR ) ;
  807.          SetTTYFocus( hWnd ) ;
  808.          hMenu = GetMenu( hWnd ) ;
  809.          EnableMenuItem( hMenu, IDM_DISCONNECT,
  810.                         MF_ENABLED | MF_BYCOMMAND ) ;
  811.          EnableMenuItem( hMenu, IDM_CONNECT,
  812.                         MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ) ;
  813.       }
  814.    }
  815.    else
  816.    {
  817.       CONNECTED( npTTYInfo ) = FALSE ;
  818.       CloseHandle( COMDEV( npTTYInfo ) ) ;
  819.    }
  820.    // restore cursor
  821.    SetCursor( hOldCursor ) ;
  822.    return ( fRetVal ) ;
  823. } // end of OpenConnection()
  824. //---------------------------------------------------------------------------
  825. //  BOOL NEAR SetupConnection( HWND hWnd )
  826. //
  827. //  Description:
  828. //     This routines sets up the DCB based on settings in the
  829. //     TTY info structure and performs a SetCommState().
  830. //
  831. //  Parameters:
  832. //     HWND hWnd
  833. //        handle to TTY window
  834. //
  835. //  Win-32 Porting Issues:
  836. //     - Win-32 requires a slightly different processing of the DCB.
  837. //       Changes were made for configuration of the hardware handshaking
  838. //       lines.
  839. //
  840. //---------------------------------------------------------------------------
  841. BOOL NEAR SetupConnection( HWND hWnd )
  842. {
  843.    BOOL       fRetVal ;
  844.    BYTE       bSet ;
  845.    DCB        dcb ;
  846.    NPTTYINFO  npTTYInfo ;
  847.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  848.       return ( FALSE ) ;
  849.    dcb.DCBlength = sizeof( DCB ) ;
  850.    GetCommState( COMDEV( npTTYInfo ), &dcb ) ;
  851.    dcb.BaudRate = BAUDRATE( npTTYInfo ) ;
  852.    dcb.ByteSize = BYTESIZE( npTTYInfo ) ;
  853.    dcb.Parity = PARITY( npTTYInfo ) ;
  854.    dcb.StopBits = STOPBITS( npTTYInfo ) ;
  855.    // setup hardware flow control
  856.    bSet = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_DTRDSR) != 0) ;
  857.    dcb.fOutxDsrFlow = bSet ;
  858.    if (bSet)
  859.       dcb.fDtrControl = DTR_CONTROL_HANDSHAKE ;
  860.    else
  861.       dcb.fDtrControl = DTR_CONTROL_ENABLE ;
  862.    bSet = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_RTSCTS) != 0) ;
  863. dcb.fOutxCtsFlow = bSet ;
  864.    if (bSet)
  865.       dcb.fRtsControl = RTS_CONTROL_HANDSHAKE ;
  866.    else
  867.       dcb.fRtsControl = RTS_CONTROL_ENABLE ;
  868.    // setup software flow control
  869.    bSet = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_XONXOFF) != 0) ;
  870.    dcb.fInX = dcb.fOutX = bSet ;
  871.    dcb.XonChar = ASCII_XON ;
  872.    dcb.XoffChar = ASCII_XOFF ;
  873.    dcb.XonLim = 100 ;
  874.    dcb.XoffLim = 100 ;
  875.    // other various settings
  876.    dcb.fBinary = TRUE ;
  877.    dcb.fParity = TRUE ;
  878.    fRetVal = SetCommState( COMDEV( npTTYInfo ), &dcb ) ;
  879.    return ( fRetVal ) ;
  880. } // end of SetupConnection()
  881. //---------------------------------------------------------------------------
  882. //  BOOL NEAR CloseConnection( HWND hWnd )
  883. //
  884. //  Description:
  885. //     Closes the connection to the port.  Resets the connect flag
  886. //     in the TTYINFO struct.
  887. //
  888. //  Parameters:
  889. //     HWND hWnd
  890. //        handle to TTY window
  891. //
  892. //  Win-32 Porting Issues:
  893. //     - Needed to stop secondary thread.  SetCommMask() will signal the
  894. //       WaitCommEvent() event and the thread will halt when the
  895. //       CONNECTED() flag is clear.
  896. //     - Use new PurgeComm() API to clear communications driver before
  897. //       closing device.
  898. //
  899. //---------------------------------------------------------------------------
  900. BOOL NEAR CloseConnection( HWND hWnd )
  901. {
  902.    HMENU      hMenu ;
  903.    NPTTYINFO  npTTYInfo ;
  904.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  905.       return ( FALSE ) ;
  906.    // set connected flag to FALSE
  907.    CONNECTED( npTTYInfo ) = FALSE ;
  908.    // disable event notification and wait for thread
  909.    // to halt
  910.    SetCommMask( COMDEV( npTTYInfo ), 0 ) ;
  911.    // block until thread has been halted
  912.    while(THREADID(npTTYInfo) != 0);
  913.    // kill the focus
  914.    KillTTYFocus( hWnd ) ;
  915.    // drop DTR
  916.    EscapeCommFunction( COMDEV( npTTYInfo ), CLRDTR ) ;
  917.    // purge any outstanding reads/writes and close device handle
  918.    PurgeComm( COMDEV( npTTYInfo ), PURGE_TXABORT | PURGE_RXABORT |
  919.                                    PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
  920.    CloseHandle( COMDEV( npTTYInfo ) ) ;
  921.    // change the selectable items in the menu
  922.    hMenu = GetMenu( hWnd ) ;
  923.    EnableMenuItem( hMenu, IDM_DISCONNECT,
  924.                    MF_GRAYED | MF_DISABLED | MF_BYCOMMAND ) ;
  925.    EnableMenuItem( hMenu, IDM_CONNECT,
  926.                    MF_ENABLED | MF_BYCOMMAND ) ;
  927.    return ( TRUE ) ;
  928. } // end of CloseConnection()
  929. //---------------------------------------------------------------------------
  930. //  int NEAR ReadCommBlock( HWND hWnd, LPSTR lpszBlock, int nMaxLength )
  931. //
  932. //  Description:
  933. //     Reads a block from the COM port and stuffs it into
  934. //     the provided buffer.
  935. //
  936. //  Parameters:
  937. //     HWND hWnd
  938. //        handle to TTY window
  939. //
  940. //     LPSTR lpszBlock
  941. //        block used for storage
  942. //
  943. //     int nMaxLength
  944. //        max length of block to read
  945. //
  946. //  Win-32 Porting Issues:
  947. //     - ReadComm() has been replaced by ReadFile() in Win-32.
  948. //     - Overlapped I/O has been implemented.
  949. //
  950. //---------------------------------------------------------------------------
  951. int NEAR ReadCommBlock( HWND hWnd, LPSTR lpszBlock, int nMaxLength )
  952. {
  953.    BOOL       fReadStat ;
  954.    COMSTAT    ComStat ;
  955.    DWORD      dwErrorFlags;
  956.    DWORD      dwLength;
  957.    DWORD      dwError;
  958.    char       szError[ 10 ] ;
  959.    NPTTYINFO  npTTYInfo ;
  960.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  961.       return ( FALSE ) ;
  962.    // only try to read number of bytes in queue
  963.    ClearCommError( COMDEV( npTTYInfo ), &dwErrorFlags, &ComStat ) ;
  964.    dwLength = min( (DWORD) nMaxLength, ComStat.cbInQue ) ;
  965.    if (dwLength > 0)
  966.    {
  967.       fReadStat = ReadFile( COMDEV( npTTYInfo ), lpszBlock,
  968.                     dwLength, &dwLength, &READ_OS( npTTYInfo ) ) ;
  969.       if (!fReadStat)
  970.       {
  971.          if (GetLastError() == ERROR_IO_PENDING)
  972.          {
  973.             OutputDebugString("nrIO Pending");
  974.             // We have to wait for read to complete.
  975.             // This function will timeout according to the
  976.             // CommTimeOuts.ReadTotalTimeoutConstant variable
  977.             // Every time it times out, check for port errors
  978.             while(!GetOverlappedResult( COMDEV( npTTYInfo ),
  979.                &READ_OS( npTTYInfo ), &dwLength, TRUE ))
  980.             {
  981.                dwError = GetLastError();
  982.                if(dwError == ERROR_IO_INCOMPLETE)
  983.                   // normal result if not finished
  984.                   continue;
  985.                else
  986.                {
  987.                   // an error occurred, try to recover
  988.                   wsprintf( szError, "<CE-%u>", dwError ) ;
  989.                   WriteTTYBlock( hWnd, szError, lstrlen( szError ) ) ;
  990.                   ClearCommError( COMDEV( npTTYInfo ), &dwErrorFlags, &ComStat ) ;
  991.                   if ((dwErrorFlags > 0) && DISPLAYERRORS( npTTYInfo ))
  992.                   {
  993.                   wsprintf( szError, "<CE-%u>", dwErrorFlags ) ;
  994.                   WriteTTYBlock( hWnd, szError, lstrlen( szError ) ) ;
  995.                   }
  996.                   break;
  997.                }
  998.             }
  999.       }
  1000.          else
  1001.          {
  1002.             // some other error occurred
  1003.             dwLength = 0 ;
  1004.             ClearCommError( COMDEV( npTTYInfo ), &dwErrorFlags, &ComStat ) ;
  1005.             if ((dwErrorFlags > 0) && DISPLAYERRORS( npTTYInfo ))
  1006.             {
  1007.             wsprintf( szError, "<CE-%u>", dwErrorFlags ) ;
  1008.             WriteTTYBlock( hWnd, szError, lstrlen( szError ) ) ;
  1009.             }
  1010.          }
  1011.       }
  1012.    }
  1013.    return ( dwLength ) ;
  1014. } // end of ReadCommBlock()
  1015. //---------------------------------------------------------------------------
  1016. //  BOOL NEAR WriteCommBlock( HWND hWnd, BYTE *pByte )
  1017. //
  1018. //  Description:
  1019. //     Writes a block of data to the COM port specified in the associated
  1020. //     TTY info structure.
  1021. //
  1022. //  Parameters:
  1023. //     HWND hWnd
  1024. //        handle to TTY window
  1025. //
  1026. //     BYTE *pByte
  1027. //        pointer to data to write to port
  1028. //
  1029. //  Win-32 Porting Issues:
  1030. //     - WriteComm() has been replaced by WriteFile() in Win-32.
  1031. //     - Overlapped I/O has been implemented.
  1032. //
  1033. //---------------------------------------------------------------------------
  1034. BOOL NEAR WriteCommBlock( HWND hWnd, LPSTR lpByte , DWORD dwBytesToWrite)
  1035. {
  1036.    BOOL        fWriteStat ;
  1037.    DWORD       dwBytesWritten ;
  1038.    NPTTYINFO   npTTYInfo ;
  1039.    DWORD       dwErrorFlags;
  1040.    DWORD    dwError;
  1041.    DWORD       dwBytesSent=0;
  1042.    COMSTAT     ComStat;
  1043.    char        szError[ 128 ] ;
  1044.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  1045.       return ( FALSE ) ;
  1046.    fWriteStat = WriteFile( COMDEV( npTTYInfo ), lpByte, dwBytesToWrite,
  1047.                            &dwBytesWritten, &WRITE_OS( npTTYInfo ) ) ;
  1048.    // Note that normally the code will not execute the following
  1049.    // because the driver caches write operations. Small I/O requests
  1050.    // (up to several thousand bytes) will normally be accepted
  1051.    // immediately and WriteFile will return true even though an
  1052.    // overlapped operation was specified
  1053.    if (!fWriteStat)
  1054.    {
  1055.       if(GetLastError() == ERROR_IO_PENDING)
  1056.       {
  1057.          // We should wait for the completion of the write operation
  1058.          // so we know if it worked or not
  1059.          // This is only one way to do this. It might be beneficial to
  1060.          // place the write operation in a separate thread
  1061.          // so that blocking on completion will not negatively
  1062.          // affect the responsiveness of the UI
  1063.          // If the write takes too long to complete, this
  1064.          // function will timeout according to the
  1065.          // CommTimeOuts.WriteTotalTimeoutMultiplier variable.
  1066.          // This code logs the timeout but does not retry
  1067.          // the write.
  1068.          while(!GetOverlappedResult( COMDEV( npTTYInfo ),
  1069.             &WRITE_OS( npTTYInfo ), &dwBytesWritten, TRUE ))
  1070.          {
  1071.             dwError = GetLastError();
  1072.             if(dwError == ERROR_IO_INCOMPLETE)
  1073.             {
  1074.                // normal result if not finished
  1075.                dwBytesSent += dwBytesWritten;
  1076.                continue;
  1077.             }
  1078.             else
  1079.             {
  1080.                // an error occurred, try to recover
  1081.                wsprintf( szError, "<CE-%u>", dwError ) ;
  1082.                WriteTTYBlock( hWnd, szError, lstrlen( szError ) ) ;
  1083.                ClearCommError( COMDEV( npTTYInfo ), &dwErrorFlags, &ComStat ) ;
  1084.                if ((dwErrorFlags > 0) && DISPLAYERRORS( npTTYInfo ))
  1085.                {
  1086.                   wsprintf( szError, "<CE-%u>", dwErrorFlags ) ;
  1087.                   WriteTTYBlock( hWnd, szError, lstrlen( szError ) ) ;
  1088.                }
  1089.                break;
  1090.             }
  1091.          }
  1092.          dwBytesSent += dwBytesWritten;
  1093.          if( dwBytesSent != dwBytesToWrite )
  1094.              wsprintf(szError,"nProbable Write Timeout: Total of %ld bytes sent", dwBytesSent);
  1095.          else
  1096.              wsprintf(szError,"n%ld bytes written", dwBytesSent);
  1097.          OutputDebugString(szError);
  1098.       }
  1099.       else
  1100.       {
  1101.          // some other error occurred
  1102.          ClearCommError( COMDEV( npTTYInfo ), &dwErrorFlags, &ComStat ) ;
  1103.          if ((dwErrorFlags > 0) && DISPLAYERRORS( npTTYInfo ))
  1104.          {
  1105.             wsprintf( szError, "<CE-%u>", dwErrorFlags ) ;
  1106.             WriteTTYBlock( hWnd, szError, lstrlen( szError ) ) ;
  1107.          }
  1108.          return ( FALSE );
  1109.       }
  1110.    }
  1111.    return ( TRUE ) ;
  1112. } // end of WriteCommBlock()
  1113. //---------------------------------------------------------------------------
  1114. //  BOOL NEAR WriteTTYBlock( HWND hWnd, LPSTR lpBlock, int nLength )
  1115. //
  1116. //  Description:
  1117. //     Writes block to TTY screen.  Nothing fancy - just
  1118. //     straight TTY.
  1119. // gl
  1120. //  Parameters:
  1121. //     HWND hWnd
  1122. //        handle to TTY window
  1123. //
  1124. //     LPSTR lpBlock
  1125. //        far pointer to block of data
  1126. //
  1127. //     int nLength
  1128. //        length of block
  1129. //
  1130. //---------------------------------------------------------------------------
  1131. BOOL NEAR WriteTTYBlock( HWND hWnd, LPSTR lpBlock, int nLength )
  1132. {
  1133.    int        i ;
  1134.    NPTTYINFO  npTTYInfo ;
  1135.    RECT       rect ;
  1136.    if (NULL == (npTTYInfo = GETNPTTYINFO( hWnd )))
  1137.       return ( FALSE ) ;
  1138.    for (i = 0 ; i < nLength; i++)
  1139.    {
  1140.       switch (lpBlock[ i ])
  1141.       {
  1142.          case ASCII_BEL:
  1143.             // Bell
  1144.             MessageBeep( 0 ) ;
  1145.             break ;
  1146.          case ASCII_BS:
  1147.             // Backspace
  1148.             if (COLUMN( npTTYInfo ) > 0)
  1149.                COLUMN( npTTYInfo ) -- ;
  1150.             MoveTTYCursor( hWnd ) ;
  1151.             break ;
  1152.          case ASCII_CR:
  1153.             // Carriage return
  1154.             COLUMN( npTTYInfo ) = 0 ;
  1155.             MoveTTYCursor( hWnd ) ;
  1156.             if (!NEWLINE( npTTYInfo ))
  1157.                break;
  1158.             // fall through
  1159.          case ASCII_LF:
  1160.             // Line feed
  1161.             if (ROW( npTTYInfo )++ == MAXROWS - 1)
  1162.             {
  1163.                _fmemmove( (LPSTR) (SCREEN( npTTYInfo )),
  1164.                           (LPSTR) (SCREEN( npTTYInfo ) + MAXCOLS),
  1165.                           (MAXROWS - 1) * MAXCOLS ) ;
  1166.                _fmemset( (LPSTR) (SCREEN( npTTYInfo ) + (MAXROWS - 1) * MAXCOLS),
  1167.                          ' ', MAXCOLS ) ;
  1168.                InvalidateRect( hWnd, NULL, FALSE ) ;
  1169.                ROW( npTTYInfo )-- ;
  1170.             }
  1171.             MoveTTYCursor( hWnd ) ;
  1172.             break ;
  1173.          default:
  1174.             *(SCREEN( npTTYInfo ) + ROW( npTTYInfo ) * MAXCOLS +
  1175.                 COLUMN( npTTYInfo )) = lpBlock[ i ] ;
  1176.             rect.left = (COLUMN( npTTYInfo ) * XCHAR( npTTYInfo )) -
  1177.                         XOFFSET( npTTYInfo ) ;
  1178.             rect.right = rect.left + XCHAR( npTTYInfo ) ;
  1179.             rect.top = (ROW( npTTYInfo ) * YCHAR( npTTYInfo )) -
  1180.                        YOFFSET( npTTYInfo ) ;
  1181.             rect.bottom = rect.top + YCHAR( npTTYInfo ) ;
  1182.             InvalidateRect( hWnd, &rect, FALSE ) ;
  1183.             // Line wrap
  1184.             if (COLUMN( npTTYInfo ) < MAXCOLS - 1)
  1185.                COLUMN( npTTYInfo )++ ;
  1186.             else if (AUTOWRAP( npTTYInfo ))
  1187.                WriteTTYBlock( hWnd, "rn", 2 ) ;
  1188.             break;
  1189.       }
  1190.    }
  1191.    return ( TRUE ) ;
  1192. } // end of WriteTTYBlock()
  1193. //---------------------------------------------------------------------------
  1194. //  VOID NEAR GoModalDialogBoxParam( HINSTANCE hInstance,
  1195. //                                   LPCSTR lpszTemplate, HWND hWnd,
  1196. //                                   DLGPROC lpDlgProc, LPARAM lParam )
  1197. //
  1198. //  Description:
  1199. //     It is a simple utility function that simply performs the
  1200. //     MPI and invokes the dialog box with a DWORD paramter.
  1201. //
  1202. //  Parameters:
  1203. //     similar to that of DialogBoxParam() with the exception
  1204. //     that the lpDlgProc is not a procedure instance
  1205. //
  1206. //---------------------------------------------------------------------------
  1207. VOID NEAR GoModalDialogBoxParam( HINSTANCE hInstance, LPCSTR lpszTemplate,
  1208.                                  HWND hWnd, DLGPROC lpDlgProc, LPARAM lParam )
  1209. {
  1210.    DLGPROC  lpProcInstance ;
  1211.    lpProcInstance = (DLGPROC) MakeProcInstance( (FARPROC) lpDlgProc,
  1212.                                                 hInstance ) ;
  1213.    DialogBoxParam( hInstance, lpszTemplate, hWnd, lpProcInstance, lParam ) ;
  1214.    FreeProcInstance( (FARPROC) lpProcInstance ) ;
  1215. } // end of GoModalDialogBoxParam()
  1216. //---------------------------------------------------------------------------
  1217. //  BOOL FAR PASCAL AboutDlgProc( HWND hDlg, UINT uMsg,
  1218. //                                WPARAM wParam, LPARAM lParam )
  1219. //
  1220. //  Description:
  1221. //     Simulates the Windows System Dialog Box.
  1222. //
  1223. //  Parameters:
  1224. //     Same as standard dialog procedures.
  1225. //
  1226. //---------------------------------------------------------------------------
  1227. BOOL FAR PASCAL AboutDlgProc( HWND hDlg, UINT uMsg,
  1228.                               WPARAM wParam, LPARAM lParam )
  1229. {
  1230.    switch (uMsg)
  1231.    {
  1232.       case WM_INITDIALOG:
  1233.       {
  1234.          char         szBuffer[ MAXLEN_TEMPSTR ], szTemp[ MAXLEN_TEMPSTR ];
  1235.          WORD         wRevision, wVersion ;
  1236. #ifdef ABOUTDLG_USEBITMAP
  1237.          // if we are using the bitmap, hide the icon
  1238.          ShowWindow( GetDlgItem( hDlg, IDD_ABOUTICON ), SW_HIDE ) ;
  1239. #endif
  1240.          // sets up the version number for Windows
  1241.          wVersion = LOWORD( GetVersion() ) ;
  1242.          wRevision = HIBYTE( wVersion ) ;
  1243.          wVersion = LOBYTE( wVersion ) ;
  1244.          GetDlgItemText( hDlg, IDD_TITLELINE, szTemp, sizeof( szTemp ) ) ;
  1245.          wsprintf( szBuffer, szTemp, wVersion, wRevision ) ;
  1246.          SetDlgItemText( hDlg, IDD_TITLELINE, szBuffer ) ;
  1247.          // sets up version number for TTY
  1248.          GetDlgItemText( hDlg, IDD_VERSION, szTemp, sizeof( szTemp ) ) ;
  1249.          wsprintf( szBuffer, szTemp, VER_MAJOR, VER_MINOR, VER_BUILD ) ;
  1250.          SetDlgItemText( hDlg, IDD_VERSION, (LPSTR) szBuffer ) ;
  1251.          // get by-line
  1252.          LoadString( GETHINST( hDlg ), IDS_BYLINE, szBuffer,
  1253.                      sizeof( szBuffer ) ) ;
  1254.          SetDlgItemText( hDlg, IDD_BYLINE, szBuffer ) ;
  1255.          SetDlgItemText( hDlg, IDD_WINDOWSMODE, "NT Mode" ) ;
  1256.       }
  1257.       return ( TRUE ) ;
  1258. #ifdef ABOUTDLG_USEBITMAP
  1259.       // used to paint the bitmap
  1260.       case WM_PAINT:
  1261.       {
  1262.          HBITMAP      hBitMap ;
  1263.          HDC          hDC, hMemDC ;
  1264.          PAINTSTRUCT  ps ;
  1265.          // load bitmap and display it
  1266.          hDC = BeginPaint( hDlg, &ps ) ;
  1267.          if (NULL != (hMemDC = CreateCompatibleDC( hDC )))
  1268.          {
  1269.             hBitMap = LoadBitmap( GETHINST( hDlg ),
  1270.                                   MAKEINTRESOURCE( TTYBITMAP ) ) ;
  1271.             hBitMap = SelectObject( hMemDC, hBitMap ) ;
  1272.             BitBlt( hDC, 10, 10, 64, 64, hMemDC, 0, 0, SRCCOPY ) ;
  1273.             DeleteObject( SelectObject( hMemDC, hBitMap ) ) ;
  1274.             DeleteDC( hMemDC ) ;
  1275.          }
  1276.          EndPaint( hDlg, &ps ) ;
  1277.       }
  1278.       break ;
  1279. #endif
  1280.       case WM_COMMAND:
  1281.          if (LOWORD( wParam ) == IDD_OK)
  1282.          {
  1283.             EndDialog( hDlg, TRUE ) ;
  1284.             return ( TRUE ) ;
  1285.          }
  1286.          break;
  1287.    }
  1288.    return ( FALSE ) ;
  1289. } // end of AboutDlgProc()
  1290. //---------------------------------------------------------------------------
  1291. //  VOID NEAR FillComboBox( HINSTANCE hInstance, HWND hCtrlWnd, int nIDString,
  1292. //                          WORD NEAR *npTable, WORD wTableLen,
  1293. //                          WORD wCurrentSetting )
  1294. //
  1295. //  Description:
  1296. //     Fills the given combo box with strings from the resource
  1297. //     table starting at nIDString.  Associated items are
  1298. //     added from given table.  The combo box is notified of
  1299. //     the current setting.
  1300. //
  1301. //  Parameters:
  1302. //     HINSTANCE hInstance
  1303. //        handle to application instance
  1304. //
  1305. //     HWND hCtrlWnd
  1306. //        handle to combo box control
  1307. //
  1308. //     int nIDString
  1309. //        first resource string id
  1310. //
  1311. //     DWORD NEAR *npTable
  1312. //        near point to table of associated values
  1313. //
  1314. //     WORD wTableLen
  1315. //        length of table
  1316. //
  1317. //     DWORD dwCurrentSetting
  1318. //        current setting (for combo box selection)
  1319. //
  1320. //---------------------------------------------------------------------------
  1321. VOID NEAR FillComboBox( HINSTANCE hInstance, HWND hCtrlWnd, int nIDString,
  1322.                         DWORD NEAR *npTable, WORD wTableLen,
  1323.                         DWORD dwCurrentSetting )
  1324. {
  1325.    char  szBuffer[ MAXLEN_TEMPSTR ] ;
  1326.    WORD  wCount, wPosition ;
  1327.    for (wCount = 0; wCount < wTableLen; wCount++)
  1328.    {
  1329.       // load the string from the string resources and
  1330.       // add it to the combo box
  1331.       LoadString( hInstance, nIDString + wCount, szBuffer, sizeof( szBuffer ) ) ;
  1332.       wPosition = LOWORD( SendMessage( hCtrlWnd, CB_ADDSTRING, 0,
  1333.                                        (LPARAM) (LPSTR) szBuffer ) ) ;
  1334.       // use item data to store the actual table value
  1335.       SendMessage( hCtrlWnd, CB_SETITEMDATA, (WPARAM) wPosition,
  1336.                    (LPARAM) *(npTable + wCount) ) ;
  1337.       // if this is our current setting, select it
  1338.       if (*(npTable + wCount) == dwCurrentSetting)
  1339.          SendMessage( hCtrlWnd, CB_SETCURSEL, (WPARAM) wPosition, 0L ) ;
  1340.    }
  1341. } // end of FillComboBox()
  1342. //---------------------------------------------------------------------------
  1343. //  BOOL NEAR SettingsDlgInit( HWND hDlg )
  1344. //
  1345. //  Description:
  1346. //     Puts current settings into dialog box (via CheckRadioButton() etc.)
  1347. //
  1348. //  Parameters:
  1349. //     HWND hDlg
  1350. //        handle to dialog box
  1351. //
  1352. //  Win-32 Porting Issues:
  1353. //     - Constants require DWORD arrays for baud rate table, etc.
  1354. //     - There is no "MAXCOM" function in Win-32.  Number of COM ports
  1355. //       is assumed to be 4.
  1356. //
  1357. //---------------------------------------------------------------------------
  1358. BOOL NEAR SettingsDlgInit( HWND hDlg )
  1359. {
  1360.    char       szBuffer[ MAXLEN_TEMPSTR ], szTemp[ MAXLEN_TEMPSTR ] ;
  1361.    NPTTYINFO  npTTYInfo ;
  1362.    WORD       wCount, wMaxCOM, wPosition ;
  1363.    if (NULL == (npTTYInfo = (NPTTYINFO) GET_PROP( hDlg, ATOM_TTYINFO )))
  1364.       return ( FALSE ) ;
  1365.    wMaxCOM = MAXPORTS ;
  1366.    // load the COM prefix from resources
  1367.    LoadString( GETHINST( hDlg ), IDS_COMPREFIX, szTemp, sizeof( szTemp ) ) ;
  1368.    // fill port combo box and make initial selection
  1369.    for (wCount = 0; wCount < wMaxCOM; wCount++)
  1370.    {
  1371.       wsprintf( szBuffer, "%s%d", (LPSTR) szTemp, wCount + 1 ) ;
  1372.       SendDlgItemMessage( hDlg, IDD_PORTCB, CB_ADDSTRING, 0,
  1373.                           (LPARAM) (LPSTR) szBuffer ) ;
  1374.    }
  1375.    SendDlgItemMessage( hDlg, IDD_PORTCB, CB_SETCURSEL,
  1376.                        (WPARAM) (PORT( npTTYInfo ) - 1), 0L ) ;
  1377.    // disable COM port combo box if connection has already been
  1378.    // established (e.g. OpenComm() already successful)
  1379.    EnableWindow( GetDlgItem( hDlg, IDD_PORTCB ), !CONNECTED( npTTYInfo ) ) ;
  1380.    // fill baud combo box and make initial selection
  1381.    FillComboBox( GETHINST( hDlg ), GetDlgItem( hDlg, IDD_BAUDCB ),
  1382.                  IDS_BAUD110, BaudTable,
  1383.                  sizeof( BaudTable ) / sizeof( BaudTable[ 0 ] ),
  1384.                  BAUDRATE( npTTYInfo ) ) ;
  1385.    // fill data bits combo box and make initial selection
  1386.    for (wCount = 5; wCount < 9; wCount++)
  1387.    {
  1388.       wsprintf( szBuffer, "%d", wCount ) ;
  1389.       wPosition = LOWORD( SendDlgItemMessage( hDlg, IDD_DATABITSCB,
  1390.                                               CB_ADDSTRING, 0,
  1391.                                               (LPARAM) (LPSTR) szBuffer ) ) ;
  1392.       // if current selection, tell the combo box
  1393.       if (wCount == BYTESIZE( npTTYInfo ))
  1394.          SendDlgItemMessage( hDlg, IDD_DATABITSCB, CB_SETCURSEL,
  1395.                              (WPARAM) wPosition, 0L ) ;
  1396.    }
  1397.    // fill parity combo box and make initial selection
  1398.    FillComboBox( GETHINST( hDlg ), GetDlgItem( hDlg, IDD_PARITYCB ),
  1399.                  IDS_PARITYNONE, ParityTable,
  1400.                  sizeof( ParityTable ) / sizeof( ParityTable[ 0 ] ),
  1401.                  PARITY( npTTYInfo ) ) ;
  1402.    // fill stop bits combo box and make initial selection
  1403.    FillComboBox( GETHINST( hDlg ), GetDlgItem( hDlg, IDD_STOPBITSCB ),
  1404.                  IDS_ONESTOPBIT, StopBitsTable,
  1405.                  sizeof( StopBitsTable ) / sizeof ( StopBitsTable ),
  1406.                  STOPBITS( npTTYInfo ) ) ;
  1407.    // initalize the flow control settings
  1408.    CheckDlgButton( hDlg, IDD_DTRDSR,
  1409.                    (FLOWCTRL( npTTYInfo ) & FC_DTRDSR) > 0 ) ;
  1410.    CheckDlgButton( hDlg, IDD_RTSCTS,
  1411.                    (FLOWCTRL( npTTYInfo ) & FC_RTSCTS) > 0 ) ;
  1412.    CheckDlgButton( hDlg, IDD_XONXOFF,
  1413.                    (FLOWCTRL( npTTYInfo ) & FC_XONXOFF) > 0 ) ;
  1414.    // other TTY settings
  1415.    CheckDlgButton( hDlg, IDD_AUTOWRAP, AUTOWRAP( npTTYInfo ) ) ;
  1416.    CheckDlgButton( hDlg, IDD_NEWLINE, NEWLINE( npTTYInfo ) ) ;
  1417.    CheckDlgButton( hDlg, IDD_LOCALECHO, LOCALECHO( npTTYInfo ) ) ;
  1418.    // control options
  1419.    // "Use CN_RECEIVE" is not valid under Win-32
  1420.    EnableWindow( GetDlgItem( hDlg, IDD_USECNRECEIVE ), FALSE ) ;
  1421.    CheckDlgButton( hDlg, IDD_DISPLAYERRORS, DISPLAYERRORS( npTTYInfo ) ) ;
  1422.    return ( TRUE ) ;
  1423. } // end of SettingsDlgInit()
  1424. //---------------------------------------------------------------------------
  1425. //  BOOL NEAR SelectTTYFont( HWND hDlg )
  1426. //
  1427. //  Description:
  1428. //     Selects the current font for the TTY screen.
  1429. //     Uses the Common Dialog ChooseFont() API.
  1430. //
  1431. //  Parameters:
  1432. //     HWND hDlg
  1433. //        handle to settings dialog
  1434. //
  1435. //---------------------------------------------------------------------------
  1436. BOOL NEAR SelectTTYFont( HWND hDlg )
  1437. {
  1438.    CHOOSEFONT  cfTTYFont ;
  1439.    NPTTYINFO   npTTYInfo ;
  1440.    if (NULL == (npTTYInfo = (NPTTYINFO) GET_PROP( hDlg, ATOM_TTYINFO )))
  1441.       return ( FALSE ) ;
  1442.    cfTTYFont.lStructSize    = sizeof( CHOOSEFONT ) ;
  1443.    cfTTYFont.hwndOwner      = hDlg ;
  1444.    cfTTYFont.hDC            = NULL ;
  1445.    cfTTYFont.rgbColors      = FGCOLOR( npTTYInfo ) ;
  1446.    cfTTYFont.lpLogFont      = &LFTTYFONT( npTTYInfo ) ;
  1447.    cfTTYFont.Flags          = CF_SCREENFONTS | CF_FIXEDPITCHONLY |
  1448.                               CF_EFFECTS | CF_INITTOLOGFONTSTRUCT ;
  1449.    cfTTYFont.lCustData      = 0 ;
  1450.    cfTTYFont.lpfnHook       = NULL ;
  1451.    cfTTYFont.lpTemplateName = NULL ;
  1452.    cfTTYFont.hInstance      = GETHINST( hDlg ) ;
  1453.    if (ChooseFont( &cfTTYFont ))
  1454.    {
  1455.      FGCOLOR( npTTYInfo ) = cfTTYFont.rgbColors ;
  1456.      ResetTTYScreen( GetParent( hDlg ), npTTYInfo ) ;
  1457.    }
  1458.    return ( TRUE ) ;
  1459. } // end of SelectTTYFont()
  1460. //---------------------------------------------------------------------------
  1461. //  BOOL NEAR SettingsDlgTerm( HWND hDlg )
  1462. //
  1463. //  Description:
  1464. //     Puts dialog contents into TTY info structure.
  1465. //
  1466. //  Parameters:
  1467. //     HWND hDlg
  1468. //        handle to settings dialog
  1469. //
  1470. //  Win-32 Porting Issues:
  1471. //     - Baud rate requires DWORD values.
  1472. //
  1473. //---------------------------------------------------------------------------
  1474. BOOL NEAR SettingsDlgTerm( HWND hDlg )
  1475. {
  1476.    NPTTYINFO  npTTYInfo ;
  1477.    WORD       wSelection ;
  1478.    if (NULL == (npTTYInfo = (NPTTYINFO) GET_PROP( hDlg, ATOM_TTYINFO )))
  1479.       return ( FALSE ) ;
  1480.    // get port selection
  1481.    PORT( npTTYInfo ) =
  1482.       LOBYTE( LOWORD( SendDlgItemMessage( hDlg, IDD_PORTCB,
  1483.                                           CB_GETCURSEL,
  1484.                                           0, 0L ) ) + 1 ) ;
  1485.    // get baud rate selection
  1486.    wSelection =
  1487.       LOWORD( SendDlgItemMessage( hDlg, IDD_BAUDCB, CB_GETCURSEL,
  1488.                                   0, 0L ) ) ;
  1489.    BAUDRATE( npTTYInfo ) =
  1490.       SendDlgItemMessage( hDlg, IDD_BAUDCB, CB_GETITEMDATA,
  1491.                           (WPARAM) wSelection, 0L ) ;
  1492.    // get data bits selection
  1493.    BYTESIZE( npTTYInfo ) =
  1494.       LOBYTE( LOWORD( SendDlgItemMessage( hDlg, IDD_DATABITSCB,
  1495.                                           CB_GETCURSEL,
  1496.                                           0, 0L ) ) + 5 ) ;
  1497.    // get parity selection
  1498.    wSelection =
  1499.       LOWORD( SendDlgItemMessage( hDlg, IDD_PARITYCB, CB_GETCURSEL,
  1500.                                   0, 0L ) ) ;
  1501.    PARITY( npTTYInfo ) =
  1502.       LOBYTE( LOWORD( SendDlgItemMessage( hDlg, IDD_PARITYCB,
  1503.                                           CB_GETITEMDATA,
  1504.                                           (WPARAM) wSelection,
  1505.                                           0L ) ) ) ;
  1506.    // get stop bits selection
  1507.    wSelection =
  1508.       LOWORD( SendDlgItemMessage( hDlg, IDD_STOPBITSCB, CB_GETCURSEL,
  1509.                                   0, 0L ) ) ;
  1510.    STOPBITS( npTTYInfo ) =
  1511.       LOBYTE( LOWORD( SendDlgItemMessage( hDlg, IDD_STOPBITSCB,
  1512.                                           CB_GETITEMDATA,
  1513.                                           (WPARAM) wSelection, 0L ) ) ) ;
  1514.    // get flow control settings
  1515.    FLOWCTRL( npTTYInfo ) = 0 ;
  1516.    if (IsDlgButtonChecked( hDlg, IDD_DTRDSR ))
  1517.       FLOWCTRL( npTTYInfo ) |= FC_DTRDSR ;
  1518.    if (IsDlgButtonChecked( hDlg, IDD_RTSCTS ))
  1519.       FLOWCTRL( npTTYInfo ) |= FC_RTSCTS ;
  1520.    if (IsDlgButtonChecked( hDlg, IDD_XONXOFF ))
  1521.       FLOWCTRL( npTTYInfo ) |= FC_XONXOFF ;
  1522.    // get other various settings
  1523.    AUTOWRAP( npTTYInfo ) = IsDlgButtonChecked( hDlg, IDD_AUTOWRAP ) ;
  1524.    NEWLINE( npTTYInfo ) = IsDlgButtonChecked( hDlg, IDD_NEWLINE ) ;
  1525.    LOCALECHO( npTTYInfo ) = IsDlgButtonChecked( hDlg, IDD_LOCALECHO ) ;
  1526.    // control options
  1527.    USECNRECEIVE( npTTYInfo ) = IsDlgButtonChecked( hDlg, IDD_USECNRECEIVE ) ;
  1528.    DISPLAYERRORS( npTTYInfo ) = IsDlgButtonChecked( hDlg, IDD_DISPLAYERRORS ) ;
  1529.    return ( TRUE ) ;
  1530. } // end of SettingsDlgTerm()
  1531. //---------------------------------------------------------------------------
  1532. //  BOOL FAR PASCAL SettingsDlgProc( HWND hDlg, UINT uMsg,
  1533. //                                   WPARAM wParam, LPARAM lParam )
  1534. //
  1535. //  Description:
  1536. //     This handles all of the user preference settings for
  1537. //     the TTY.
  1538. //
  1539. //  Parameters:
  1540. //     same as all dialog procedures
  1541. //
  1542. //  Win-32 Porting Issues:
  1543. //     - npTTYInfo is a DWORD in Win-32.
  1544. //
  1545. //---------------------------------------------------------------------------
  1546. BOOL FAR PASCAL SettingsDlgProc( HWND hDlg, UINT uMsg,
  1547.                                  WPARAM wParam, LPARAM lParam )
  1548. {
  1549.    switch (uMsg)
  1550.    {
  1551.       case WM_INITDIALOG:
  1552.       {
  1553.          NPTTYINFO  npTTYInfo ;
  1554.          // get & save pointer to TTY info structure
  1555.          npTTYInfo = (NPTTYINFO) lParam ;
  1556.          SET_PROP( hDlg, ATOM_TTYINFO, (HANDLE) npTTYInfo ) ;
  1557.          return ( SettingsDlgInit( hDlg ) ) ;
  1558.       }
  1559.       case WM_COMMAND:
  1560.          switch ( LOWORD( wParam ))
  1561.          {
  1562.             case IDD_FONT:
  1563.                return ( SelectTTYFont( hDlg ) ) ;
  1564.             case IDD_OK:
  1565.                // Copy stuff into structure
  1566.                SettingsDlgTerm( hDlg ) ;
  1567.                EndDialog( hDlg, TRUE ) ;
  1568.                return ( TRUE ) ;
  1569.             case IDD_CANCEL:
  1570.                // Just end
  1571.                EndDialog( hDlg, TRUE ) ;
  1572.                return ( TRUE ) ;
  1573.          }
  1574.          break;
  1575.       case WM_DESTROY:
  1576.          REMOVE_PROP( hDlg, ATOM_TTYINFO ) ;
  1577.          break ;
  1578.    }
  1579.    return ( FALSE ) ;
  1580. } // end of SettingsDlgProc()
  1581. //************************************************************************
  1582. //  DWORD FAR PASCAL CommWatchProc( LPSTR lpData )
  1583. //
  1584. //  Description:
  1585. //     A secondary thread that will watch for COMM events.
  1586. //
  1587. //  Parameters:
  1588. //     LPSTR lpData
  1589. //        32-bit pointer argument
  1590. //
  1591. //  Win-32 Porting Issues:
  1592. //     - Added this thread to watch the communications device and
  1593. //       post notifications to the associated window.
  1594. //
  1595. //************************************************************************
  1596. DWORD FAR PASCAL CommWatchProc( LPSTR lpData )
  1597. {
  1598.    DWORD       dwEvtMask ;
  1599.    NPTTYINFO   npTTYInfo = (NPTTYINFO) lpData ;
  1600.    OVERLAPPED  os ;
  1601. int        nLength ;
  1602.    BYTE       abIn[ MAXBLOCK + 1] ;
  1603.    memset( &os, 0, sizeof( OVERLAPPED ) ) ;
  1604.    // create I/O event used for overlapped read
  1605.    os.hEvent = CreateEvent( NULL,    // no security
  1606.                             TRUE,    // explicit reset req
  1607.                             FALSE,   // initial event reset
  1608.                             NULL ) ; // no name
  1609.    if (os.hEvent == NULL)
  1610.    {
  1611.       MessageBox( NULL, "Failed to create event for thread!", "TTY Error!",
  1612.                   MB_ICONEXCLAMATION | MB_OK ) ;
  1613.       return ( FALSE ) ;
  1614.    }
  1615.    if (!SetCommMask( COMDEV( npTTYInfo ), EV_RXCHAR ))
  1616.       return ( FALSE ) ;
  1617.    while ( CONNECTED( npTTYInfo ) )
  1618.    {
  1619.       dwEvtMask = 0 ;
  1620.       WaitCommEvent( COMDEV( npTTYInfo ), &dwEvtMask, NULL );
  1621.       if ((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
  1622.       {
  1623.          do
  1624.          {
  1625.             if (nLength = ReadCommBlock( hTTYWnd, (LPSTR) abIn, MAXBLOCK ))
  1626.             {
  1627.                WriteTTYBlock( hTTYWnd, (LPSTR) abIn, nLength ) ;
  1628.                // force a paint
  1629.                UpdateWindow( hTTYWnd ) ;
  1630.             }
  1631.          }
  1632.          while ( nLength > 0 ) ;
  1633.       }
  1634.    }
  1635.    // get rid of event handle
  1636.    CloseHandle( os.hEvent ) ;
  1637.    // clear information in structure (kind of a "we're done flag")
  1638.    THREADID( npTTYInfo ) = 0 ;
  1639.    HTHREAD( npTTYInfo ) = NULL ;
  1640.    return( TRUE ) ;
  1641. } // end of CommWatchProc()
  1642. //---------------------------------------------------------------------------
  1643. //  End of File: tty.c
  1644. //---------------------------------------------------------------------------