📄 status.c
字号:
/*-----------------------------------------------------------------------------
This is a part of the Microsoft Source Code Samples.
Copyright (C) 1995 Microsoft Corporation.
All rights reserved.
This source code is only intended as a supplement to
Microsoft Development Tools and/or WinHelp documentation.
See these sources for detailed information regarding the
Microsoft samples programs.
MODULE: Status.c
PURPOSE: Controls the status dialog at bottom of screen
Functions:
OpenStatusToolBar - Creates the status dialog
CreateStatusEditFont - Creates the status edit control font
StatusDlgProc - Status dialog procedure
InitStatusMessage - Initializes the status message mechanism
StatusMessage - Updates status edit control
UpdateStatus - Creates a status message node (entry point
for other threads
ReportModemStatus - Updates modem status controls
CheckModemStatus - Calls GetCommModemStatus and ReportModemStatus
ReportComStat - Updates comm status controls based on
COMSTAT structure (from ClearCommError)
ReportCommError - Reports comm errors when they occur
ReportStatusEvent - Reports comm events when they occur
-----------------------------------------------------------------------------*/
#include <windows.h>
#include <string.h>
#include <stdio.h>
#include "MTTTY.h"
#define MAX_STATUS_LENGTH 100
//
// Prototypes for functions called only within this file
//
void ReportStatusEvent( DWORD );
void ReportCommError( void );
void ReportModemStatus( DWORD );
BOOL CALLBACK StatusDlgProc( HWND, UINT, WPARAM, LPARAM );
void InitStatusMessage( void );
/*-----------------------------------------------------------------------------
FUNCTION: OpenStatusToolbar(HWND)
PURPOSE: Opens the modeless status dialog
PARAMETERS:
hWnd - Handle of window which owns the dialog
HISTORY: Date: Author: Comment:
10/27/95 AllenD Wrote it
/*-----------------------------------------------------------------------------*/
void OpenStatusToolbar(HWND hWnd)
{
ghWndStatusDlg = CreateDialog(ghInst, MAKEINTRESOURCE(IDD_STATUSDIALOG), hWnd, StatusDlgProc);
if (ghWndStatusDlg == NULL)
ErrorReporter("CreateDialog (Status Dialog)");
return;
}
/*-----------------------------------------------------------------------------
FUNCTION: CreateStatusEditFont
PURPOSE: Creates the font for the status edit control
RETURN: HFONT of new font created
HISTORY: Date: Author: Comment:
10/27/95 AllenD Wrote it
-----------------------------------------------------------------------------*/
HFONT CreateStatusEditFont()
{
LOGFONT lf = {0};
HFONT hFont;
lf.lfHeight = 14 ;
lf.lfCharSet = ANSI_CHARSET ;
lf.lfOutPrecision = OUT_DEFAULT_PRECIS ;
lf.lfClipPrecision = CLIP_DEFAULT_PRECIS ;
lf.lfQuality = DEFAULT_QUALITY ;
lf.lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS ;
hFont = CreateFontIndirect(&lf);
return hFont;
}
/*-----------------------------------------------------------------------------
FUNCTION: StatusDlgProc(HWND, UINT, WPARAM, LPARAM)
PURPOSE: Provides the dialog procedure for the status dialog
PARAMETERS:
hWndDlg - Dialog window handle
uMsg - Window message
wParam - message parameter (depends on message)
lParam - message parameter (depends on message)
RETURN:
TRUE if message is handled
FALSE if message is not handled
Exception is WM_INITDIALOG: returns FALSE since focus is not set
HISTORY: Date: Author: Comment:
10/27/95 AllenD Wrote it
-----------------------------------------------------------------------------*/
BOOL CALLBACK StatusDlgProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BOOL fRet = FALSE;
switch(uMsg)
{
case WM_INITDIALOG: // setup dialog with defaults
SendMessage(GetDlgItem(hWndDlg, IDC_STATUSEDIT), WM_SETFONT, (WPARAM)ghFontStatus, 0);
InitStatusMessage();
break;
case WM_COMMAND:
{
switch(LOWORD(wParam))
{
case IDC_ABORTBTN:
SendMessage(ghwndMain, WM_COMMAND, ID_TRANSFER_ABORTSENDING, MAKELPARAM(IDC_ABORTBTN,0) );
fRet = TRUE;
break;
case IDC_STATCTS:
case IDC_STATDSR:
case IDC_STATRING:
case IDC_STATRLSD:
CheckModemStatus(TRUE);
fRet = TRUE;
break;
case IDC_CTSHOLDCHK:
case IDC_DSRHOLDCHK:
case IDC_RLSDHOLDCHK:
case IDC_XOFFHOLDCHK:
case IDC_XOFFSENTCHK:
case IDC_EOFSENTCHK:
case IDC_TXIMCHK:
CheckComStat(TRUE);
fRet = TRUE;
break;
default:
break;
}
}
break;
default:
break;
}
return fRet;
}
/*-----------------------------------------------------------------------------
FUNCTION: InitStatusMessage
PURPOSE: Initializes status message heap and linked list
HISTORY: Date: Author: Comment:
11/21/95 AllenD Wrote it
-----------------------------------------------------------------------------*/
void InitStatusMessage()
{
SYSTEM_INFO SysInfo;
GetSystemInfo(&SysInfo);
ghStatusMessageHeap = HeapCreate(0, SysInfo.dwPageSize, 0);
if (ghStatusMessageHeap == NULL)
ErrorReporter("HeapCreate (Status message)");
glpStatusMessageHead = HeapAlloc(ghStatusMessageHeap, HEAP_ZERO_MEMORY, sizeof(STATUS_MESSAGE));
glpStatusMessageTail = glpStatusMessageHead;
gnStatusIndex = 0;
/*
Queue the initial status message.
This won't show up until the ReaderAndStatusProc function
is called when the threads are created after the port is connected.
*/
UpdateStatus("Status message go here:\r\n");
return;
}
/*-----------------------------------------------------------------------------
FUNCTION: StatusMessage
PURPOSE: Retrieves status message from status message linked list
and updates status edit control.
COMMENTS: Called from ReaderAndStatusProc when the status event
has been set. Clears edit control when number of characters
exceeds MAX_STATUS_BUFFER.
HISTORY: Date: Author: Comment:
11/21/95 AllenD Wrote it
-----------------------------------------------------------------------------*/
void StatusMessage()
{
STATUS_MESSAGE * lpStatusMessage;
DWORD dwRes;
HWND hEdit;
BOOL bRes;
hEdit = GetDlgItem (ghWndStatusDlg, IDC_STATUSEDIT);
/*
If status control has a lot of characters in it,
then wipe them out and start over
*/
if (gnStatusIndex > MAX_STATUS_BUFFER) {
SendMessageTimeout( hEdit, EM_SETSEL,
(WPARAM) (INT) 0, (LPARAM) (INT) -1,
SMTO_NORMAL | SMTO_ABORTIFHUNG,
500, &dwRes);
SendMessageTimeout( hEdit, EM_REPLACESEL,
0, (LPARAM) "",
SMTO_NORMAL | SMTO_ABORTIFHUNG,
500, &dwRes);
gnStatusIndex = 0;
}
//
// Loop through each node in the status message linked list.
//
for ( lpStatusMessage = glpStatusMessageHead->lpNext ; lpStatusMessage ; )
{
//
// if global quit event is set, then just exit this loop
//
if (WaitForSingleObject(ghThreadExitEvent, 0) == WAIT_OBJECT_0)
break;
//
// Place each status message into the status control.
//
SendMessageTimeout( hEdit, EM_SETSEL,
gnStatusIndex, gnStatusIndex,
SMTO_NORMAL | SMTO_ABORTIFHUNG,
500, &dwRes);
SendMessageTimeout( hEdit, EM_REPLACESEL,
0, (LPARAM) ((LPSTR) &(lpStatusMessage->chMessageStart)),
SMTO_NORMAL | SMTO_ABORTIFHUNG,
500, &dwRes);
gnStatusIndex += strlen(&(lpStatusMessage->chMessageStart));
//
// Update status message linked list
//
EnterCriticalSection(&gStatusCritical);
bRes = HeapFree(ghStatusMessageHeap, 0, glpStatusMessageHead);
glpStatusMessageHead = lpStatusMessage;
lpStatusMessage = lpStatusMessage->lpNext;
LeaveCriticalSection(&gStatusCritical);
if (!bRes)
ErrorReporter("HeapFree (status message)");
}
return;
}
/*-----------------------------------------------------------------------------
FUNCTION: UpdateStatus(char *)
PURPOSE: Places the passed in string into the status message linked
list and sets the event to make the message display.
PARAMETERS:
szText - message to be placed in the status control
COMMENTS: Synchronization needed in order to ensure that only
one thread at a time places a string in the list
HISTORY: Date: Author: Comment:
10/27/95 AllenD Wrote it
11/21/95 AllenD Modified to use a status message heap
-----------------------------------------------------------------------------*/
void UpdateStatus(char * szText)
{
char * szNewMsg;
DWORD dwSize;
STATUS_MESSAGE * lpStatusMessage;
static dwMessageCounter = 0;
dwMessageCounter++;
dwSize = strlen(szText) + 30; // include NULL terminator and space for counter
EnterCriticalSection(&gStatusCritical);
szNewMsg = HeapAlloc(ghStatusMessageHeap, 0, dwSize+30);
if (szNewMsg == NULL) {
LeaveCriticalSection(&gStatusCritical);
ErrorReporter("HeapAlloc (status message)");
return;
}
else {
wsprintf(szNewMsg, "%d:%s", dwMessageCounter, szText);
if (strlen(szNewMsg) > dwSize) {
LeaveCriticalSection(&gStatusCritical);
ErrorInComm("Heap Corruption in UpdateStatus\n");
}
}
lpStatusMessage = HeapAlloc(ghStatusMessageHeap, 0, sizeof(LPSTR) + dwSize );
if (lpStatusMessage == NULL) {
LeaveCriticalSection(&gStatusCritical);
ErrorReporter("HeapAlloc (status message)");
return ;
}
lpStatusMessage->lpNext = NULL;
glpStatusMessageTail->lpNext = lpStatusMessage;
glpStatusMessageTail = lpStatusMessage;
CopyMemory(&(lpStatusMessage->chMessageStart), szNewMsg, dwSize);
LeaveCriticalSection(&gStatusCritical);
SetEvent(ghStatusMessageEvent);
return ;
}
/*-----------------------------------------------------------------------------
FUNCTION: ReportModemStatus(DWORD)
PURPOSE: Reports modem status line states
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -