EditCtls.C
资源名称:tapisamp.rar [点击查看]
上传用户:woweijixie
上传日期:2018-12-11
资源大小:131k
文件大小:12k
源码类别:
TAPI编程
开发平台:
Visual C++
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- // PARTICULAR PURPOSE.
- //
- // Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
- //
- // MODULE: EditCtls.c
- //
- // PURPOSE: Handles the UI Edit controls to get data from user and display
- // data recieved from the COMM port.
- //
- // EXPORTED FUNCTIONS: These functions are for use by other modules.
- // InitEditCtls - Initialize the edit controls.
- // SizeEditCtls - Size and resize the edit controls.
- // SetFocusEditCtls - Set the focus to the correct edit control.
- // WriteToDisplayCtl - Write a string to the Display edit control.
- // PostWriteToDisplayCtl - Posts a message to the UI thread
- // with data to write.
- //
- // INTERNAL FUNCTIONS: These functions are for this module only.
- // SubclassInputEditProc - Subclass proc to catch the 'enter' keystroke.
- //
- // COMMENTS:
- // This sample uses exceptionally simple terminal emulation: none.
- // There are two edit controls involved. One for the user to type the
- // outgoing strings (called the InputCtl) and another to display both
- // transmitted and received strings (called the DisplayCtl). There is
- // absolutely *no* translation of incoming strings, and the only
- // modifications to outgoing strings is to append "/r/n" to it.
- //
- // This sample only emulates line mode transmission. The string is only
- // read from the InputCtl when the 'Enter' key is typed.
- //
- #include <windows.h>
- #include <string.h>
- #include "globals.h"
- #include "EditCtls.h"
- #include "CommCode.h"
- #include "toolbar.h"
- #include "statbar.h"
- // Maximum size of Edit control buffers
- #define MAXDISPLAYSIZE 0xF000 // Almost 64K
- #define MAXINPUTSIZE 0x400 // 1K
- #define PWM_WRITESTRING WM_USER + 741 // Arbitrary number
- HWND hWndInputCtl; // Edit control to get input from user
- HWND hWndDisplayCtl; // Edit control to display all output
- HWND hWndParent; // Parent window of edit controls
- WNDPROC lpfnInputEdit; // Storage for subclassed edit control function
- // Prototype for the subclassed procedure.
- LRESULT CALLBACK SubclassInputEditProc(
- HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
- //
- // FUNCTION: InitEditCtls(HWND)
- //
- // PURPOSE: Initialize the UI edit controls.
- //
- // PARAMETERS:
- // hWndMain - The window that is to contain the edit controls.
- //
- // RETURN VALUE:
- // TRUE if the edit controls are successfully initialized.
- //
- // COMMENTS:
- // This function should only need to be called once, when
- // creating the main window. The only reason it could fail
- // is if the edit controls couldn't be created.
- //
- BOOL InitEditCtls(HWND hWndMain)
- {
- hWndParent = hWndMain;
- if (!hWndMain)
- {
- OutputDebugString("Invalid parent hWnd for EditCtls!n");
- return FALSE;
- }
- hWndDisplayCtl = CreateWindowEx(
- WS_EX_CLIENTEDGE,
- "EDIT","",
- WS_CHILD | WS_HSCROLL | WS_VSCROLL | ES_MULTILINE
- | ES_OEMCONVERT | WS_VISIBLE | WS_BORDER,
- 0, 0, 0, 0, hWndParent,
- NULL, hInst, NULL);
- hWndInputCtl = CreateWindowEx(
- WS_EX_CLIENTEDGE,
- "EDIT","",
- WS_CHILD | ES_AUTOHSCROLL | WS_VISIBLE | WS_BORDER,
- 0, 0, 0, 0, hWndParent,
- NULL, hInst, NULL);
- if (!hWndDisplayCtl || !hWndInputCtl)
- {
- OutputDebugString("Unable to create EditCtls.n");
- return FALSE;
- }
- SendMessage(hWndInputCtl, EM_LIMITTEXT, MAXINPUTSIZE, 0);
- SendMessage(hWndDisplayCtl, EM_LIMITTEXT, MAXDISPLAYSIZE, 0);
- // This is where we subclass the input edit control
- // so we can catch the 'enter' keystroke
- lpfnInputEdit = (WNDPROC)
- SetWindowLong(hWndInputCtl, GWL_WNDPROC, (long) SubclassInputEditProc);
- return TRUE;
- }
- //
- // FUNCTION: SizeEditCtls
- //
- // PURPOSE: Sizes, resizes and positions the edit controls.
- //
- // PARAMETERS:
- // none
- //
- // RETURN VALUE:
- // none
- //
- // COMMENTS:
- // Anytime the parent window is resized, it needs to signal
- // the edit controls to also resize. The size of the edit
- // controls assumes that the edit controls are going to
- // contain the full client area of the parent, allowing for
- // the toolbar and statusbar.
- //
- void SizeEditCtls()
- {
- RECT rectParent, rectTemp;
- LONG HeightToolbar, HeightStatusbar;
- LONG HeightDisplayCtl, HeightInputCtl;
- LONG WidthCtls;
- LONG yposTopInputCtl, yposTopDisplayCtl;
- HDC hdc;
- TEXTMETRIC tm;
- // Get the client area of the parent.
- if (!GetClientRect(hWndParent, &rectParent))
- {
- OutputDebugString("GetClientRect on EditCtls parent failedn");
- return;
- }
- // leave a pixel on each side
- WidthCtls = rectParent.right - 2;
- // Allow for the toolbar at the top.
- GetWindowRect(hWndToolbar, &rectTemp);
- HeightToolbar = rectTemp.bottom - rectTemp.top;
- // Allow for the statusbar at the bottom.
- GetWindowRect(hWndStatusbar, &rectTemp);
- HeightStatusbar = rectTemp.bottom - rectTemp.top;
- // How high should the input control be?
- hdc = GetDC(hWndInputCtl);
- GetTextMetrics(hdc, &tm);
- ReleaseDC(hWndInputCtl, hdc);
- HeightInputCtl = tm.tmHeight + tm.tmExternalLeading + 6;
- // 6 == 3 extra pixels between text and edit control vertical borders.
- // Position Input control.
- yposTopInputCtl = rectParent.bottom - HeightStatusbar - HeightInputCtl - 1;
- // Position Display control.
- yposTopDisplayCtl = rectParent.top + HeightToolbar + 2;
- HeightDisplayCtl = yposTopInputCtl - yposTopDisplayCtl - 1;
- // Move them both.
- MoveWindow(
- hWndInputCtl,
- 1, yposTopInputCtl,
- WidthCtls, HeightInputCtl,
- TRUE);
- MoveWindow(
- hWndDisplayCtl,
- 1, yposTopDisplayCtl,
- WidthCtls, HeightDisplayCtl,
- TRUE);
- }
- //
- // FUNCTION: SetFocusEditCtls
- //
- // PURPOSE: Sets the focus to the correct edit control.
- //
- // PARAMETERS:
- // none
- //
- // RETURN VALUE:
- // none
- //
- // COMMENTS:
- // Everytime the parent window gets focus, it needs to signal
- // the edit controls to set focus also. This very simple
- // algorythm always sets focus to the Input control.
- //
- void SetFocusEditCtls()
- {
- DefWindowProc(hWndParent, WM_SETFOCUS, (WPARAM) NULL, (LPARAM) NULL);
- if (GetFocus() == hWndParent)
- SetFocus(hWndInputCtl);
- return;
- }
- //
- // FUNCTION: SubclassInputEditProc
- //
- // PURPOSE: Subclass proceedure of Input control.
- //
- // PARAMETERS:
- // Standard WNDPROC parameters.
- //
- // RETURN VALUE:
- // Standard WNDPROC return value.
- //
- // COMMENTS:
- // We subclass the Input edit control so that we can catch the 'Enter'
- // keystroke (VK_RETURN). This is how we know when the user wants to
- // transmit something to the COMM port. This indeed means that only
- // line based terminal emulation is supported by this sample. However,
- // it makes editing the outgoing text much easier.
- //
- // WriteCommString is the call that writes a string to the COMM port.
- // However, the string that is written *must* be allocated with
- // LocalAlloc, and if WriteCommString succeeds, then it will also
- // LocalFree the string. If WriteCommString fails, then it refused
- // the string and its our job to free it.
- //
- LRESULT CALLBACK SubclassInputEditProc(
- HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch(message)
- {
- case WM_CHAR:
- // Found a RETURN keystroke!
- if ((TCHAR) wParam == VK_RETURN)
- {
- LPSTR pszString;
- long lSizeofString;
- // Get the size of the string to send.
- lSizeofString =
- SendMessage(hWndInputCtl, WM_GETTEXTLENGTH, 0, 0);
- // Allocate enough space for the string and "r "
- pszString = (LPSTR) LocalAlloc(LPTR, lSizeofString +2);
- // Get the string
- SendMessage(hWndInputCtl, WM_GETTEXT,
- lSizeofString + 1, (LPARAM) pszString);
- // Terminate it.
- strcat(pszString, "r");
- lSizeofString += 1;
- // If the write to Comm failed, its probably because
- // a connection isn't made yet.
- if (WriteCommString(pszString, lSizeofString))
- {
- // This is what we'd do to local echo user input
- // Unnecessary usually.
- //WriteToOutputEdit(pszString, lSizeofString);
- ;
- }
- else
- {
- WriteToDisplayCtl("Not yet connectedr", 20);
- // The comm code refused the string, so we must free it.
- LocalFree(pszString);
- }
- // Clear the Input control.
- SendMessage(hWndInputCtl, WM_SETTEXT, 0, (LPARAM) "");
- // Don't let default processing handle the RETURN key.
- return 0;
- }
- break;
- case PWM_WRITESTRING:
- WriteToDisplayCtl((LPSTR) lParam, (DWORD) wParam);
- LocalFree((LPSTR) lParam);
- break;
- default:
- break;
- }
- return CallWindowProc(lpfnInputEdit, hWnd, message, wParam, lParam);
- }
- //
- // FUNCTION: WriteToDisplayCtl(LPSTR, DWORD)
- //
- // PURPOSE: Writes a string to the Display control.
- //
- // PARAMETERS:
- // lpNewString - The string to display.
- // dwSizeofNewString - The length of the string.
- //
- // RETURN VALUE:
- // none.
- //
- // COMMENTS:
- //
- void WriteToDisplayCtl(LPSTR lpNewString, DWORD dwSizeofNewString)
- {
- DWORD dwSizeofEdit;
- dwSizeofEdit = SendMessage(hWndDisplayCtl, WM_GETTEXTLENGTH, 0, 0);
- if ((dwSizeofEdit + dwSizeofNewString) > MAXDISPLAYSIZE)
- {
- // Suggestion for future additions:
- // Handle edit control overflow by deleting from top of edit control
- }
- // Actually place the string into the Display control.
- SendMessage(hWndDisplayCtl, EM_SETSEL, dwSizeofEdit, dwSizeofEdit);
- SendMessage(hWndDisplayCtl, EM_REPLACESEL, 0, (LPARAM) lpNewString);
- SendMessage(hWndDisplayCtl, EM_SETSEL,
- dwSizeofEdit+dwSizeofNewString, dwSizeofEdit+dwSizeofNewString);
- }
- //
- // FUNCTION: PostWriteToDisplayCtl(LPSTR, DWORD)
- //
- // PURPOSE: Writes a string to the Display control.
- //
- // PARAMETERS:
- // lpNewString - The string to display.
- // dwSizeofNewString - The length of the string.
- //
- // RETURN VALUE:
- // none.
- //
- // COMMENTS:
- //
- // Its very important that when data is recieved from the comm port,
- // the thread reading the comm port doesn't have to wait for the
- // data to be interpreted. Instead, it posts the data to the main UI
- // thread to be handled when it is convenient. This is the API to
- // wrap up the PostMessage.
- //
- // Note that the string posted must be LocalAlloc()d, and its the job
- // of the window recieving the message to LocalFree it.
- //
- BOOL PostWriteToDisplayCtl(LPSTR lpNewString, DWORD dwSizeofNewString)
- {
- return PostMessage(hWndInputCtl, PWM_WRITESTRING,
- (WPARAM)dwSizeofNewString, (LPARAM) lpNewString);
- }