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

📄 interact.cxx

📁 windows mobile phone source code
💻 CXX
📖 第 1 页 / 共 3 页
字号:
/*
 * interact.cxx
 *
 * Interactor classes implementation.
 *
 * 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: interact.cxx,v $
 * Revision 1.76  2001/01/29 03:00:58  robertj
 * Added function to determine if window is iconic, zoomed or normal.
 *
 * Revision 1.75  2000/04/13 23:18:43  robertj
 * Fixed problems with sizing controls with scroll bars.
 *
 * Revision 1.74  2000/03/17 20:32:22  robertj
 * Fixed race conditions in mult-threaded windows (dialogs in particular)
 *
 * Revision 1.73  1999/11/16 06:51:42  robertj
 * Created PCustomListBox to allow motif native code PStringListBox implementation
 *
 * Revision 1.72  1999/10/24 11:41:34  robertj
 * Fixed bug in SetDimensions() to allow for a window with a menu.
 *
 * Revision 1.71  1999/08/25 02:42:13  robertj
 * Fixed problem with creating windows in background threads, not happening until have a message sent.
 *
 * Revision 1.70  1999/08/17 03:46:42  robertj
 * Fixed usage of inlines in optimised version.
 *
 * Revision 1.69  1999/08/07 07:13:23  robertj
 * Fixed problems with "balloon help" text popup.
 *
 * Revision 1.68  1999/03/29 03:39:55  robertj
 * Changed semantics of PTitledWindow::OnClose() function.
 *
 * Revision 1.67  1999/02/16 08:08:07  robertj
 * MSVC 6.0 compatibility changes.
 *
 * Revision 1.66  1998/09/24 03:42:44  robertj
 * Added open software license.
 *
 * Revision 1.65  1998/09/24 01:55:53  robertj
 * Fixed problems with resizing windows with built in scroll bars.
 *
 * Revision 1.64  1998/09/22 15:15:29  robertj
 * Added more support for common control callbacks, can now set message result.
 * Added correction for invisible scroll bars in resizing windows.
 *
 * Revision 1.63  1998/09/21 13:31:03  robertj
 * Changes to support new PListView class. Different call back method.
 *
 * Revision 1.62  1998/09/14 13:17:22  robertj
 * Fixed memory leak on delete of PStringList, not deleting all its contents.
 * Fixed major memory (resource) leak in control painting.
 *
 * Revision 1.61  1998/09/04 07:03:22  robertj
 * Fixed possible crash on focus change. Depends on timeing of messages.
 * Fixed SetFont() really setting font. If target is not control font may not be set in this way.
 *
 * Revision 1.60  1998/01/26 00:19:53  robertj
 * Fixed colour of static controls in windows and dialogs.
 *
 * Revision 1.59  1997/04/27 05:50:31  robertj
 * DLL support.
 *
 * Revision 1.58  1996/10/31 12:39:57  robertj
 * Added RCS keywords.
 *
 */

#include <pwlib.h>

#if !P_USE_INLINES
#include <pwlib/pwmisc.inl>
#endif


void PInteractor::Construct(PInteractor * par, HWND hWnd, BOOL hiddenChild)
{
  parent = par;

  if (parent != NULL) {
    if (!hiddenChild)
      parent->children.Append(this);
    owner = parent->owner;
    cursorMode = UseParentCursor;
  }
  else {
    owner = &PApplication::Current();
    cursorMode = UseCurrentCursor;
  }

  _hWnd = hWnd;
  if (_hWnd != NULL) {
    owner->AddWindowHandle(_hWnd, this);
    HFONT hFont = (HFONT)(UINT)SendMessage(_hWnd, WM_GETFONT, 0, 0L);
    if (hFont != NULL)
      font = PRealFont(hFont);
    else
      SetFont(parent->GetFont(), TRUE);
  }
  else {
    if (parent != NULL)
      SetFont(parent->GetFont(), TRUE);
  }

  foregroundColour = owner->GetWindowFgColour();
  backgroundColour = owner->GetWindowBkColour();

  caretVisible = 1;

  _in_WM_PAINT = FALSE;
  mouseTrackInteractor = NULL;
  mouseTrackCanvas = NULL;
  hBackgroundBrush = NULL;
}


PInteractor::~PInteractor()
{
  if (hBackgroundBrush != NULL)
    DeleteObject(hBackgroundBrush);

  if (GetFocusInteractor() == this)
    SetFocusInteractor(parent);

  if (parent!=NULL && parent->children.GetObjectsIndex(this) != P_MAX_INDEX) {
    parent->children.DisallowDeleteObjects();
    parent->children.Remove(this);
    parent->children.AllowDeleteObjects();
  }

  if (_hWnd != NULL && _hWnd != P_DEAD_WINDOW)
    DestroyWindow(_hWnd);
}


PObject::Comparison PInteractor::Compare(const PObject & obj) const
{
  PAssert(obj.IsDescendant(PInteractor::Class()), PInvalidParameter);
  return GetHWND() ==
                ((const PInteractor &)obj).GetHWND() ? EqualTo : GreaterThan;
}


void PInteractor::SetFont(const PFont & newFont, BOOL toChildren)
{
  font = PRealFont(newFont);

  if (_hWnd != NULL)
    SetWndFont();

  if (toChildren) {
    for (PINDEX i = 0; i < children.GetSize(); i++)
      children[i].SetFont(font, TRUE);
  }
}


void PInteractor::_SetPosition(PORDINATE x, PORDINATE y,
                               PositionOrigin xOrigin, PositionOrigin yOrigin)
{
  PDim myDim = GetStructureBounds(ScreenCoords).Dimensions();
  PDim scrDim = owner->GetPrimaryScreenSize();
  PDim parDim = scrDim;
  PPoint org;
  PInteractor * p = this;
  if (parent != NULL) {
    p = parent;
    parDim = p->GetStructureBounds(ScreenCoords).Dimensions();
    ClientToScreen(p->GetHWND(), org);
  }

  switch (xOrigin) {
    case TopLeftParent:
    case CentreParent :
    case BottomRightParent :
      x = p->ToPixelsX(x) + org.X();
      break;

    case TopLeftPixels:
    case CentrePixels :
    case BottomRightPixels :
      x = x + org.X();
  }

  switch (xOrigin) {
    case CentreParent :
    case CentrePixels :
      x += ((PORDINATE)parDim.Width() - (PORDINATE)myDim.Width())/2;
      break;

    case BottomRightParent :
    case BottomRightPixels :
      x += (PORDINATE)parDim.Width() - (PORDINATE)myDim.Width();
      break;

    case CentreScreen :
      x += ((PORDINATE)scrDim.Width() - (PORDINATE)myDim.Width())/2;
      break;

    case BottomRightScreen :
      x = owner->GetScreenRect().Right() - (PORDINATE)myDim.Width();
  }

  switch (yOrigin) {
    case TopLeftParent:
    case CentreParent :
    case BottomRightParent :
      y = p->ToPixelsY(y) + org.Y();
      break;

    case TopLeftPixels:
    case CentrePixels :
    case BottomRightPixels :
      y = y + org.Y();
  }

  switch (yOrigin) {
    case CentreParent :
    case CentrePixels :
      y += ((PORDINATE)parDim.Height() - (PORDINATE)myDim.Height())/2;
      break;

    case BottomRightParent :
    case BottomRightPixels :
      y += (PORDINATE)parDim.Height() - (PORDINATE)myDim.Height();
      break;

    case CentreScreen :
      y += ((PORDINATE)scrDim.Height() - (PORDINATE)myDim.Height())/2;
      break;

    case BottomRightScreen :
      y = owner->GetScreenRect().Height() - (PORDINATE)myDim.Height();
  }

  if ((_styleBits&0xc0000000) == WS_CHILD) {
    POINT pt;
    pt.x = x;
    pt.y = y;
    ScreenToClient(p->GetHWND(), &pt);
    x = (PORDINATE)pt.x;
    y = (PORDINATE)pt.y;
  }

  SetWindowPos(GetHWND(), NULL, x, y, 0, 0, SWP_NOSIZE|SWP_NOZORDER);
}


PPoint PInteractor::GetPosition(CoordinateSystem coords) const
{
  RECT r;
  GetWindowRect(GetHWND(), &r);
  PPoint p((PORDINATE)r.left, (PORDINATE)r.top);

  if (coords == ScreenCoords)
    return p;

  if (GetParent() != NULL)
    ScreenToClient(GetParent()->GetHWND(), p);

  if (coords == PixelCoords)
    return p;

  const PInteractor * par = parent != NULL ? parent : this;
  return par->FromPixels(p);
}


PPoint PInteractor::ToScreen(const PPoint & pt, CoordinateSystem coords) const
{
  PPoint p;
  switch (coords) {
    case LocalCoords :
      p = ToPixels(pt);
      break;
    case PixelCoords :
      p = pt;
      break;
    case ScreenCoords :
      return pt;
  }
  ClientToScreen(GetHWND(), p);
  return p;
}


PPoint PInteractor::FromScreen(const PPoint & pt, CoordinateSystem coords) const
{
  if (coords == ScreenCoords)
    return pt;

  PPoint p = pt;
  ScreenToClient(GetHWND(), p);
  return coords == PixelCoords ? p : ToPixels(p);
}


void PInteractor::_SetDimensions(PDIMENSION width, PDIMENSION height,
                                 CoordinateSystem coords)
{
  GetHWND();

  if (coords == LocalCoords) {
    width = ToPixelsDX(width);
    height = ToPixelsDY(height);
  }

  switch (_styleBits&WS_CAPTION) {
    case WS_CAPTION :
      height += (PDIMENSION)GetSystemMetrics(SM_CYCAPTION);
      break;
    case WS_BORDER :
      width += (PDIMENSION)GetSystemMetrics(SM_CXBORDER)*2;
      height += (PDIMENSION)GetSystemMetrics(SM_CYBORDER)*2;
      break;
    case WS_DLGFRAME :
      width += (PDIMENSION)GetSystemMetrics(SM_CXDLGFRAME)*2;
      height += (PDIMENSION)GetSystemMetrics(SM_CYDLGFRAME)*2;
      break;
  }

  if ((_styleBits&WS_VSCROLL) != 0 && AdjustDimensionForScrollBar(SB_VERT))
    width += (PDIMENSION)GetSystemMetrics(SM_CXVSCROLL);

  if ((_styleBits&WS_HSCROLL) != 0 && AdjustDimensionForScrollBar(SB_HORZ))
    height += (PDIMENSION)GetSystemMetrics(SM_CYHSCROLL);

  if ((_exStyleBits&WS_EX_DLGMODALFRAME) != 0) {
    width += (PDIMENSION)GetSystemMetrics(SM_CXDLGFRAME)*2;
    height += (PDIMENSION)GetSystemMetrics(SM_CYDLGFRAME)*2;
  }
  else if ((_styleBits&WS_THICKFRAME) != 0) {
    width += (PDIMENSION)GetSystemMetrics(SM_CXFRAME)*2;
    height += (PDIMENSION)GetSystemMetrics(SM_CYFRAME)*2;
  }

  if ((_styleBits&(WS_CHILD|WS_POPUP|WS_OVERLAPPED)) != WS_CHILD && GetMenu(_hWnd) != NULL)
    height += (PDIMENSION)GetSystemMetrics(SM_CYMENU);

  SetWindowPos(_hWnd, NULL, 0, 0, width, height, SWP_NOMOVE|SWP_NOZORDER);
}


BOOL PInteractor::AdjustDimensionForScrollBar(UINT bar) const
{
  SCROLLINFO inf;
  inf.cbSize = sizeof(inf);
  inf.fMask = SIF_RANGE|SIF_PAGE;
  GetScrollInfo(_hWnd, bar, &inf);
  return inf.nMin != inf.nMax && inf.nPage < (UINT)(inf.nMax - inf.nMin);
}


PDim PInteractor::GetDimensions(CoordinateSystem coords) const
{
  PRect r;
  GetClientRect(GetHWND(), r);
  if (coords != LocalCoords)
    return r.Dimensions();
  return FromPixels(r.Dimensions());
}


PRect PInteractor::GetStructureBounds(CoordinateSystem coords) const
{
  PRect r;
  GetWindowRect(GetHWND(), r);

  if (coords == ScreenCoords)
    return r;

  PPoint p1(r.Origin());
  ScreenToClient(GetHWND(), p1);

  PPoint p2(r.Corner());
  ScreenToClient(GetHWND(), p2);

  if (coords == PixelCoords)
    return PRect(p1, p2);

  return PRect(FromPixels(p1), FromPixels(p2));
}


void PInteractor::_Invalidate(PORDINATE x, PORDINATE y,
                              PDIMENSION dx, PDIMENSION dy,
                              CoordinateSystem coords)
{
  RECT cr;
  GetClientRect(GetHWND(), &cr);

  RECT r;
  switch (coords) {
    case LocalCoords :
      r.left = ToPixelsX(x);
      r.top = ToPixelsY(y);
      r.right = ToPixelsX(x+dx);
      r.bottom = ToPixelsY(y+dy);
      break;

    case PixelCoords :
      r.left = x;
      r.top = y;
      r.right = x+dx;
      r.bottom = y+dy;
      break;

    default : // ScreenCoords
      RECT wr;
      GetWindowRect(GetHWND(), &wr);
      r.left = wr.left+x;
      r.top = wr.top+y;
      r.right = x+dx;
      r.bottom = y+dy;
  }

  if (r.left < cr.left)
    r.left = cr.left;
  if (r.right > cr.right)
    r.right = cr.right;
  if (r.top < cr.top)
    r.top = cr.top;
  if (r.bottom > cr.bottom)
    r.bottom = cr.bottom;

  InvalidateRect(_hWnd, &r, FALSE);
}


void PInteractor::_Validate(PORDINATE x, PORDINATE y,
                            PDIMENSION dx, PDIMENSION dy,
                            CoordinateSystem coords)
{
  RECT cr;
  GetClientRect(GetHWND(), &cr);

  RECT r;
  switch (coords) {
    case LocalCoords :
      r.left = ToPixelsX(x);
      r.top = ToPixelsY(y);
      r.right = ToPixelsX(x+dx);
      r.bottom = ToPixelsY(y+dy);
      break;

    case PixelCoords :
      r.left = x;
      r.top = y;
      r.right = x+dx;
      r.bottom = y+dy;
      break;

    default : // ScreenCoords
      RECT wr;
      GetWindowRect(GetHWND(), &wr);
      r.left = wr.left+x;
      r.top = wr.top+y;
      r.right = x+dx;
      r.bottom = y+dy;
  }

  if (r.left < cr.left)
    r.left = cr.left;
  if (r.right > cr.right)
    r.right = cr.right;
  if (r.top < cr.top)
    r.top = cr.top;
  if (r.bottom > cr.bottom)
    r.bottom = cr.bottom;

  ValidateRect(GetHWND(), &r);
}


void PInteractor::ReleaseMouse()
{
  if (HasMouse())
    ReleaseCapture();
}


void PInteractor::SetCursorToParent(BOOL useParent)
{
  if (cursorMode == UseParentCursor || cursorMode == UseCurrentCursor) {
    cursorMode = useParent ? UseParentCursor : UseCurrentCursor;
    parent->SetWndCursor();
  }
}


void PInteractor::SetCursor(const PCursor & newCursor)
{
  if (cursorMode == UseParentCursor || cursorMode == UseCurrentCursor) {
    cursorMode = UseCurrentCursor;
    cursor = newCursor;
    if (_hWnd != P_DEAD_WINDOW &&
                    ContainsPoint(GetCursorPos(ScreenCoords), ScreenCoords))
      SetWndCursor();
  }
}


void PInteractor::SetWndCursor() const
{
  if (cursorMode == UseParentCursor && parent != NULL)
    parent->SetWndCursor();
  else
    ::SetCursor(cursor.GetHCURSOR());
}


void PInteractor::_SetCursorPos(PORDINATE x, PORDINATE y,
                                CoordinateSystem coords)
{
  PPoint p(x, y);
  switch (coords) {
    case LocalCoords :
      p = ToPixels(p);
    case PixelCoords :
      ClientToScreen(GetHWND(), p);
      break;
    case ScreenCoords :
      break;
  }
  ::SetCursorPos(p.X(), p.Y());
}


PPoint PInteractor::GetCursorPos(CoordinateSystem coords) const
{
  PPoint p;
  ::GetCursorPos(p);

  if (coords == ScreenCoords)
    return p;

  ::ScreenToClient(GetHWND(), p);
  if (coords == PixelCoords)
    return p;

  return FromPixels(p);

⌨️ 快捷键说明

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