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

📄 mswin.cxx

📁 windows mobile phone source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*
 * mswin.cxx
 *
 * General class implementations for 16 bit Windows.
 *
 * Portable Windows Library
 *
 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
 * All Rights Reserved.
 *
 * Contributor(s): ______________________________________.
 *
 * $Log: mswin.cxx,v $
 * Revision 1.18  2001/08/07 03:20:39  robertj
 * Fixed close of DLL so flagged as closed, thanks Stefan Ditscheid.
 *
 * Revision 1.17  1998/09/24 03:30:51  robertj
 * Added open software license.
 *
 * Revision 1.16  1996/02/15 14:55:02  robertj
 * Win16 compatibility
 *
 * Revision 1.15  1996/01/28 02:55:33  robertj
 * WIN16 support.
 *
 * Revision 1.14  1995/12/10 11:58:37  robertj
 * Added WIN32 registry support for PConfig objects.
 *
 * Revision 1.13  1995/08/24 12:40:52  robertj
 * Changed PChannel so not a PContainer.
 *
 * Revision 1.12  1995/07/02 01:24:45  robertj
 * Added running of hidden VM for DOS program in PPipeChannel.
 *
 * Revision 1.11  1995/06/17 00:59:23  robertj
 * Moved PPipeChannel::Execute from common dos/windows to individual files.
 *
 * Revision 1.10  1995/03/12 05:00:06  robertj
 * Re-organisation of DOS/WIN16 and WIN32 platforms to maximise common code.
 * Used built-in equate for WIN32 API (_WIN32).
 *
 * Revision 1.9  1995/01/09  12:28:00  robertj
 * Added implementation for PConfig::Environment
 *
 * Revision 1.8  1994/10/23  05:41:29  robertj
 * Fixed config file bugs.
 *
 * Revision 1.7  1994/08/22  00:18:02  robertj
 * Fixed bug in serial comms timers.
 *
 * Revision 1.6  1994/08/04  13:24:27  robertj
 * Added DCB so can set paraemters on closed channel.
 *
 * Revision 1.5  1994/07/27  06:00:10  robertj
 * Backup
 *
 * Revision 1.4  1994/07/21  12:35:18  robertj
 * *** empty log message ***
 *
 * Revision 1.3  1994/07/17  11:01:04  robertj
 * Ehancements, implementation, bug fixes etc.
 *
 * Revision 1.2  1994/07/02  03:18:09  robertj
 * Multi-threading implementation.
 *
 * Revision 1.1  1994/06/25  12:13:01  robertj
 * Initial revision
 *
// Revision 1.1  1994/04/01  14:39:35  robertj
// Initial revision
//
 */

#include "ptlib.h"
#include <errno.h>
#include <fcntl.h>

#include <stdresid.h>


extern "C" HINSTANCE _hInstance;


///////////////////////////////////////////////////////////////////////////////
// PTime

PString PTime::GetTimeSeparator()
{
  PString str;
  GetProfileString("intl", "sTime", ":", str.GetPointer(100), 99);
  str.MakeMinimumSize();
  return str;
}


BOOL PTime::GetTimeAMPM()
{
  return GetProfileInt("intl", "iTime", 0) != 0;
}


PString PTime::GetTimeAM()
{
  PString str;
  GetProfileString("intl", "s1159", "am", str.GetPointer(100), 99);
  str.MakeMinimumSize();
  return str;
}


PString PTime::GetTimePM()
{
  PString str;
  GetProfileString("intl", "s2359", "pm", str.GetPointer(100), 99);
  str.MakeMinimumSize();
  return str;
}


PString PTime::GetDayName(Weekdays dayOfWeek, NameType type)
{
  static const char * const weekdays[] = {
    "Sunday", "Monday", "Tuesday", "Wednesday",
    "Thursday", "Friday", "Saturday"
  };
  static const char * const abbrev_weekdays[] = {
    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
  };
  PString str;
  if (LoadString(_hInstance, dayOfWeek+
        (type != FullName ? PSTD_ID_STR_ABBREV_WEEKDAYS : PSTD_ID_STR_WEEKDAYS),
        str.GetPointer(100), 99) == 0)
    return (type != FullName ? abbrev_weekdays : weekdays)[dayOfWeek];
  str.MakeMinimumSize();
  return str;
}


PString PTime::GetDateSeparator()
{
  PString str;
  GetProfileString("intl", "sDate", "-", str.GetPointer(100), 99);
  str.MakeMinimumSize();
  return str;
}


PString PTime::GetMonthName(Months month, NameType type)
{
  static const char * const months[] = { "",
    "January", "February", "March", "April", "May", "June",
    "July", "August", "September", "October", "November", "December"
  };
  static const char * const abbrev_months[] = {
    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  };
  PString str;
  if (LoadString(_hInstance, month+
       (UINT)(type != FullName ? PSTD_ID_STR_ABBREV_MONTHS : PSTD_ID_STR_MONTHS),
       str.GetPointer(100), 99) == 0)
    return (type != FullName ? abbrev_months : months)[month];
  str.MakeMinimumSize();
  return str;
}


PTime::DateOrder PTime::GetDateOrder()
{
  return (DateOrder)GetProfileInt("intl", "iDate", 0);
}


BOOL PTime::IsDaylightSavings()
{
  return FALSE;
}


int PTime::GetTimeZone(TimeZoneType type)
{
  return 0;
}


PString PTime::GetTimeZoneString(TimeZoneType type)
{
  return "";
}


///////////////////////////////////////////////////////////////////////////////
// PSerialChannel

void PSerialChannel::Construct()
{
  char str[50];
  strcpy(str, "com1");
  GetProfileString("ports", str, "9600,n,8,1,x", &str[5], sizeof(str)-6);
  str[4] = ':';
  if (!BuildCommDCB(str, &deviceControlBlock)) {
    osError = EINVAL;
    lastError = BadParameter;
  }
}


PString PSerialChannel::GetName() const
{
  if (IsOpen())
    return psprintf("COM%i", os_handle+1);

  return PString();
}


BOOL PSerialChannel::IsReadBlocked(PObject * obj)
{
  PSerialChannel & chan = *(PSerialChannel *)PAssertNULL(obj);
  COMSTAT stat;
  GetCommError(chan.os_handle, &stat);
  return stat.cbInQue <= 0 &&
         (chan.readTimeout == PMaxTimeInterval || chan.readTimer.IsRunning());
}


BOOL PSerialChannel::Read(void * buf, PINDEX len)
{
  lastReadCount = 0;

  if (!IsOpen()) {
    PThread::Yield();
    osError = EBADF;
    lastError = NotOpen;
    return FALSE;
  }

  if (readTimeout != PMaxTimeInterval)
    readTimer = readTimeout;
  if (IsReadBlocked(this))
    PThread::Current()->Block(&PSerialChannel::IsReadBlocked, this);

  lastReadCount = ReadComm(os_handle, buf, len);
  if (lastReadCount > 0)
    return TRUE;

  COMSTAT stat;
  GetCommError(os_handle, &stat);
  osError = EFAULT;
  lastReadCount = -lastReadCount;
  return lastReadCount > 0;
}


BOOL PSerialChannel::IsWriteBlocked(PObject * obj)
{
  PSerialChannel & chan = *(PSerialChannel *)PAssertNULL(obj);
  COMSTAT stat;
  GetCommError(chan.os_handle, &stat);
  return stat.cbOutQue >= OutputQueueSize &&
       (chan.writeTimeout == PMaxTimeInterval || chan.writeTimer.IsRunning());
}


BOOL PSerialChannel::Write(const void * buf, PINDEX len)
{
  lastWriteCount = 0;

  if (!IsOpen()) {
    osError = EBADF;
    lastError = NotOpen;
    return FALSE;
  }

  if (writeTimeout != PMaxTimeInterval)
    writeTimer = writeTimeout;
  if (IsWriteBlocked(this))
    PThread::Current()->Block(&PSerialChannel::IsWriteBlocked, this);

  lastWriteCount = WriteComm(os_handle, buf, len);
  if (lastWriteCount <= 0) {
    COMSTAT stat;
    GetCommError(os_handle, &stat);
    osError = EFAULT;
    lastWriteCount = -lastWriteCount;
  }
  return lastWriteCount >= len;
}


BOOL PSerialChannel::Close()
{
  if (!IsOpen()) {
    osError = EBADF;
    lastError = NotOpen;
    return FALSE;
  }

  BOOL retVal = CloseComm(os_handle) == 0;
  os_handle = -1;
  return retVal;
}


BOOL PSerialChannel::SetCommsParam(DWORD speed, BYTE data, Parity parity,
                     BYTE stop, FlowControl inputFlow, FlowControl outputFlow)
{
  if (IsOpen())
    PAssert(GetCommState(os_handle, &deviceControlBlock) == 0,
                                                        POperatingSystemError);

  switch (speed) {
    case 0 :
      break;
    case 14400 :
      deviceControlBlock.BaudRate = CBR_14400;
      break;
    case 19200 :
      deviceControlBlock.BaudRate = CBR_19200;
      break;
    case 38400 :
      deviceControlBlock.BaudRate = CBR_38400;
      break;
    case 56000 :
      deviceControlBlock.BaudRate = CBR_56000;
      break;
    case 128000 :
      deviceControlBlock.BaudRate = CBR_128000;
      break;
    case 256000 :
      deviceControlBlock.BaudRate = CBR_256000;
      break;
    default :
      if (speed > 9600) {
        osError = EINVAL;
        return FALSE;
      }
      deviceControlBlock.BaudRate = (UINT)speed;
  }

  if (data > 0)
    deviceControlBlock.ByteSize = data;

  switch (parity) {
    case NoParity :
      deviceControlBlock.Parity = NOPARITY;
      break;
    case OddParity :
      deviceControlBlock.Parity = ODDPARITY;
      break;
    case EvenParity :
      deviceControlBlock.Parity = EVENPARITY;
      break;
    case MarkParity :
      deviceControlBlock.Parity = MARKPARITY;
      break;
    case SpaceParity :
      deviceControlBlock.Parity = SPACEPARITY;
      break;
  }
  switch (stop) {
    case 1 :
      deviceControlBlock.StopBits = ONESTOPBIT;
      break;
    case 2 :
      deviceControlBlock.StopBits = TWOSTOPBITS;
      break;
  }
  switch (inputFlow) {
    case NoFlowControl :
      deviceControlBlock.fRtsflow = FALSE;
      deviceControlBlock.fInX = FALSE;
      break;
    case XonXoff :
      deviceControlBlock.fRtsflow = FALSE;
      deviceControlBlock.fInX = TRUE;
      break;
    case RtsCts :
      deviceControlBlock.fRtsflow = TRUE;
      deviceControlBlock.fInX = FALSE;
      break;
  }

  switch (outputFlow) {
    case NoFlowControl :
      deviceControlBlock.fOutxCtsFlow = FALSE;
      deviceControlBlock.fOutxDsrFlow = FALSE;
      deviceControlBlock.fOutX = FALSE;
      break;
    case XonXoff :
      deviceControlBlock.fOutxCtsFlow = FALSE;
      deviceControlBlock.fOutxDsrFlow = FALSE;
      deviceControlBlock.fOutX = TRUE;
      break;
    case RtsCts :
      deviceControlBlock.fOutxCtsFlow = TRUE;
      deviceControlBlock.fOutxDsrFlow = FALSE;
      deviceControlBlock.fOutX = FALSE;
      break;
  }

  if (!IsOpen()) {
    osError = EBADF;
    lastError = NotOpen;
    lastError = BadParameter;
    return FALSE;
  }

  if (SetCommState(&deviceControlBlock) < 0) {
    osError = EINVAL;
    return FALSE;
  }

  PAssert(GetCommState(os_handle, &deviceControlBlock) == 0,
                                                        POperatingSystemError);
  return TRUE;
}


BOOL PSerialChannel::Open(const PString & port, DWORD speed, BYTE data,
       Parity parity, BYTE stop, FlowControl inputFlow, FlowControl outputFlow)
{
  Close();

  os_handle = OpenComm(port, InputQueueSize, OutputQueueSize);
  if (os_handle < 0) {
    switch (os_handle) {
      case IE_BADID :
      case IE_HARDWARE :
        osError = ENOENT;
        lastError = NotFound;
        break;
      case IE_OPEN :
        osError = EBUSY;
        lastError = DeviceInUse;
        break;
      case IE_MEMORY :
        osError = ENOMEM;
        lastError = NoMemory;
        break;
      case IE_BAUDRATE :
      case IE_BYTESIZE :
        osError = EINVAL;
        lastError = BadParameter;
        break;
      default :
        osError = EFAULT;
        lastError = Miscellaneous;
    }
    os_handle = -1;
    return FALSE;
  }

  deviceControlBlock.Id = (BYTE)os_handle;
  SetCommState(&deviceControlBlock);

  if (!SetCommsParam(speed, data, parity, stop, inputFlow, outputFlow)) {
    CloseComm(os_handle);
    return FALSE;
  }

  SetCommEventMask(os_handle, EV_CTSS|EV_DSR|EV_RING|EV_RLSDS);
  return TRUE;
}


BOOL PSerialChannel::SetSpeed(DWORD speed)
{
  return SetCommsParam(speed,
                 0, DefaultParity, 0, DefaultFlowControl, DefaultFlowControl);
}


DWORD PSerialChannel::GetSpeed() const
{
  switch (deviceControlBlock.BaudRate) {
    case CBR_110 :
      return 110;
    case CBR_300 :
      return 300;
    case CBR_600 :
      return 600;
    case CBR_1200 :
      return 1200;
    case CBR_2400 :
      return 2400;
    case CBR_4800 :
      return 4800;
    case CBR_9600 :
      return 9600;
    case CBR_14400 :
      return 14400;
    case CBR_19200 :
      return 19200;
    case CBR_38400 :
      return 38400;
    case CBR_56000 :
      return 56000;
    case CBR_128000 :
      return 128000;
    case CBR_256000 :
      return 256000;
  }
  return deviceControlBlock.BaudRate;
}


BOOL PSerialChannel::SetDataBits(BYTE data)
{
  return SetCommsParam(0,
              data, DefaultParity, 0, DefaultFlowControl, DefaultFlowControl);
}

⌨️ 快捷键说明

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