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

📄 dialogs.cxx

📁 windows mobile phone source code
💻 CXX
📖 第 1 页 / 共 3 页
字号:
/*
 * dialogs.cxx
 *
 * Dialog 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: dialogs.cxx,v $
 * Revision 1.67  2000/09/27 01:31:52  robertj
 * Fixed problem with no control value update if press "Enter" to close dialog.
 *
 * Revision 1.66  2000/04/04 22:26:20  robertj
 * Fixed bug in PDialog when close button closes regardless of OnCancel() virtual.
 *
 * Revision 1.65  2000/03/17 20:32:22  robertj
 * Fixed race conditions in mult-threaded windows (dialogs in particular)
 *
 * Revision 1.64  2000/03/04 13:08:35  robertj
 * Moved common function in open file dialog to common source file.
 *
 * Revision 1.63  2000/03/04 10:09:38  robertj
 * Fixed bugs in open file dialog (showed up in Win2K).
 *
 * Revision 1.62  1999/11/16 06:51:42  robertj
 * Created PCustomListBox to allow motif native code PStringListBox implementation
 *
 * Revision 1.61  1999/11/01 00:07:44  robertj
 * Changed semantics of OnClose() to be the same as PTitledWindow
 *
 * Revision 1.60  1999/10/24 11:52:05  robertj
 * Fixed problems with creating/deleting dialogs from background threads.
 *
 * Revision 1.59  1999/08/25 05:13:33  robertj
 * Fixed problem with calling modal dialog from a background thread.
 *
 * Revision 1.58  1999/08/07 07:13:23  robertj
 * Fixed problems with "balloon help" text popup.
 *
 * Revision 1.57  1999/02/16 08:08:07  robertj
 * MSVC 6.0 compatibility changes.
 *
 * Revision 1.56  1998/12/12 00:43:51  robertj
 * Added functions for user request on printing selection only.
 * Fixed transfer of start and end pages from PPrintDialog.
 *
 * Revision 1.55  1998/12/02 03:50:12  robertj
 * Unix compatibility changes
 *
 * Revision 1.54  1998/09/24 03:42:39  robertj
 * Added open software license.
 *
 * Revision 1.53  1998/09/24 01:55:32  robertj
 * Fixed bug that caused modal dialog not to go away when closed from another thread.
 *
 * Revision 1.52  1998/09/22 15:09:45  robertj
 * Fixed confusion in Font Dialog, variable at different levels with same name.
 * Fixed Font Dialog not returning font that was selected.
 *
 * Revision 1.51  1998/09/17 04:25:56  robertj
 * Fixed race condition if dialog is closed by a different thread to the PProcess thrad.
 *
 * Revision 1.50  1998/09/14 13:14:20  robertj
 * Fixed memory leak on delete of PStringList, not deleting all its contents.
 * Fixed failure to update control values on non-modal dialog box initialisation.
 *
 * Revision 1.49  1998/09/04 07:01:06  robertj
 * Added a lot of DEVMODE infor for win95 to propagate from PrintDlg to PPrintCanvas.
 *
 * Revision 1.48  1998/03/20 03:12:44  robertj
 * Fixed bug in standard file dialog getting filename and folder.
 *
 * Revision 1.47  1998/03/09 07:14:31  robertj
 * Explorer based OpenDirDialog.
 * More implementation of file type lists.
 *
 * Revision 1.46  1998/03/09 01:46:45  robertj
 * Enhanced file types for standard file dialog.
 *
 * Revision 1.44  1996/11/04 03:32:25  robertj
 * Fixed bug in background colour of dialogs.
 *
 * Revision 1.43  1996/10/31 12:39:56  robertj
 * Added RCS keywords.
 *
 */

#include <pwlib.h>


class PDummyListBox : public PListBox
{
  PCLASSINFO(PDummyListBox, PListBox)
  public:
    PDummyListBox(PInteractorLayout * layout, PRESOURCE_ID ctrlID)
      : PListBox(layout, ctrlID, PNotifier(), NULL) { }

    virtual void OnDrawEntry(PINDEX, PObject &, PCanvas &, const PRect &, BOOL, BOOL)
      { }

    virtual PDim OnMeasureEntry(PINDEX, PObject &, PCanvas &)
      { return PDim(); }

    virtual BOOL IsOwnerDraw() const
      { return FALSE; }
};

#define new PNEW


///////////////////////////////////////////////////////////////////////////////
// PInteractorLayout

PInteractorLayout::PInteractorLayout(PInteractor * parent)
  : PInteractor(parent)
{
  focusInteractor = this;
  pResourceID = (PRESOURCE_ID)-1;
}


PInteractorLayout::PInteractorLayout(PInteractor * parent, PRESOURCE_ID resID)
  : PInteractor(parent)
{
  focusInteractor = this;
  pResourceID = resID;
}


PInteractorLayout::~PInteractorLayout()
{
  if (_hWnd != NULL && PThread::Current() != owner) {
    if (_hWnd != P_DEAD_WINDOW)
      PostMessage(_hWnd, WM_CLOSE, 0, 0);
    handledDestroySignal.Wait();
  }

  owner->RemoveDialog(this);
}


BOOL PEXPORTED EnumDlgChildren(HWND hWnd, PInteractorLayout * layout)
{
  if (GetParent(hWnd) != layout->GetHWND())
    return TRUE;

  PRESOURCE_ID ctrlID = (PRESOURCE_ID)GetDlgCtrlID(hWnd);
  if (ctrlID == 0xffff)
    return TRUE;

  if (layout->GetControl(ctrlID) != NULL)
    return TRUE;

  PControl * child = NULL;

  char className[20];
  GetClassName(hWnd, className, sizeof(className));
  DWORD style = GetWindowLong(hWnd, GWL_STYLE);

  if (lstrcmpi(className, "EDIT") == 0) {
    if ((style&ES_MULTILINE) != 0)
      child = new PMultiLineEditBox(layout, ctrlID, PNotifier(), NULL);
    else {
      char str[30];
      GetWindowText(hWnd, str, sizeof(str));
      SetWindowText(hWnd, "");
      if (lstrcmpi(str, "INTEDIT") == 0)
        child = new PIntegerEditBox(layout, ctrlID, PNotifier(), NULL);
      else if (lstrcmpi(str, "REALEDIT") == 0)
        child = new PFloatEditBox(layout, ctrlID, PNotifier(), NULL);
      else
        child = new PEditBox(layout, ctrlID, PNotifier(), NULL);
    }
  }
  else if (lstrcmpi(className, "STATIC") == 0) {
    switch (style&15) {
      case SS_LEFT :
      case SS_SIMPLE :
      case SS_LEFTNOWORDWRAP :
      case SS_CENTER :
      case SS_RIGHT :
        child = new PStaticText(layout, ctrlID, PNotifier(), NULL);
        break;

      case SS_ICON :
        child = new PStaticIcon(layout, ctrlID, PNotifier(), NULL);
        break;
    }
  }
  else if (lstrcmpi(className, "BUTTON") == 0) {
    switch (style&15) {
      case BS_PUSHBUTTON :
      case BS_DEFPUSHBUTTON :
        child = new PTextButton(layout, ctrlID, PNotifier(), NULL);
        break;

      case BS_AUTOCHECKBOX :
      case BS_CHECKBOX :
        child = new PCheckBox(layout, ctrlID, PNotifier(), NULL);
        break;

      case BS_AUTO3STATE :
      case BS_3STATE :
        child = new PCheck3WayBox(layout, ctrlID, PNotifier(), NULL);
        break;

      case BS_AUTORADIOBUTTON :
      case BS_RADIOBUTTON :
        child = new PRadioButton(layout, ctrlID, PNotifier(), NULL);
        break;

      case BS_GROUPBOX :
        child = new PStaticBox(layout, ctrlID, PNotifier(), NULL);
        break;
    }
  }
  else if (lstrcmpi(className, "LISTBOX") == 0) {
    if ((style&LBS_OWNERDRAWVARIABLE) == 0)
      child = new PDummyListBox(layout, ctrlID);
    else
      child = new PStringListBox(layout, ctrlID, PNotifier(), NULL);
  }
  else if (lstrcmpi(className, "COMBOBOX") == 0) {
    switch (style&15) {
      case CBS_DROPDOWN :
        child = new PChoiceBox(layout, ctrlID, PNotifier(), NULL);
        break;

      case CBS_DROPDOWNLIST :
        child = new PComboBox(layout, ctrlID, PNotifier(), NULL);
        break;
    }
  }
  else if (lstrcmpi(className, "SCROLLBAR") == 0) {
    if ((style&1) != 0)
      child = new PVerticalScrollBar(layout, ctrlID, PNotifier(), NULL);
    else
      child = new PHorizontalScrollBar(layout, ctrlID, PNotifier(), NULL);
  }

  return TRUE;
}


void PInteractorLayout::ConstructEnd(PRESOURCE_ID resID)
{
  EnumChildWindows(GetHWND(), (WNDENUMPROC)EnumDlgChildren, (LPARAM)this);

  PResourceData dialog("#5", resID);
  PResourceData strings("DIALOGSTRINGS", resID);
#if defined(_WIN32)
  PINDEX numControls = ((const DLGTEMPLATE *)(const BYTE *)dialog)->cdit;
  const WORD * strptr = (const WORD *)(const BYTE *)strings;
  const WORD * strbase;
#else
  PINDEX numControls = dialog[4];
  const char * strptr = (const char *)(const BYTE *)strings;
  const char * strbase;
#endif

  for (PINDEX i = 0; i < numControls; i++) {
    PControl & child = (PControl &)children[i];
    strbase = strptr;
    PINDEX len = 0;
    while (*strptr++ != 0)
      len++;
    if (len != 0)
      child.SetBalloonHelp(PString(strbase, len));

    while (*strptr != 0) {
      strbase = strptr;
      len = 0;
      while (*strptr++ != 0)
        len++;
      if (child.IsDescendant(PChoiceBox::Class()))
        ((PChoiceBox&)child).AddString(PString(strbase, len));
      else if (child.IsDescendant(PStringListBox::Class()))
        ((PStringListBox&)child).AddString(PString(strbase, len));
      else if (child.IsDescendant(PComboBox::Class()))
        ((PComboBox&)child).AddString(PString(strbase, len));
    }
    strptr++;
  }

  for (i = 1; i < GetNumChildren(); i++) {
    if (children[i].IsDescendant(PRadioButton::Class()) &&
                             children[i-1].IsDescendant(PRadioButton::Class()))
      ((PRadioButton &)children[i]).AddToGroup((PRadioButton &)children[i-1]);
  }

  UpdateControls();
}


void PInteractorLayout::GetCreateWinInfo(WNDCLASS & wndClass)
{
  PInteractor::GetCreateWinInfo(wndClass);

  wndClass.lpszClassName = "Dialog";
}


void PInteractorLayout::CreateHWND()
{
  if (pResourceID != -1) {
    _hWnd = CreateDialog(owner->GetInstance(),
                     MAKEINTRESOURCE(pResourceID),
                     parent->GetHWND(),
                     (DLGPROC)owner->GetWndProcPtr(PApplication::DlgProcType));
    PAssert(_hWnd != NULL, PInvalidWindow);
    PPoint pos = GetPosition(ScreenCoords);
    if (pos.X() < 0 && pos.Y() < 0)
      SetPosition(0,0,CentreParent,CentreParent);
    HFONT hFont = (HFONT)(UINT)SendMessage(_hWnd, WM_GETFONT, 0, 0L);
    if (hFont != NULL)
      font = PRealFont(hFont);
    else
      SetFont(parent->GetFont(), TRUE);
  }
  else {
    WNDCLASS dummyWndClass;
#if defined(_WIN32)
    struct {
      DLGTEMPLATE header;
      WORD  szMenuName[1], szClassName[1], szCaption[1];
      WORD  wPointSize;
      WORD  szFaceName[1];
    } emptyDlg;
    memset(&emptyDlg, 0, sizeof(emptyDlg));
    GetCreateWinInfo(dummyWndClass);
    emptyDlg.header.dwExtendedStyle = _exStyleBits;
#else
    struct {
      struct {
        DWORD style;
        BYTE  bNumberOfItems;
        WORD  x, y, cx, cy;
      } header;
      char  szMenuName[1], szClassName[1], szCaption[1];
      WORD  wPointSize;
      char  szFaceName[1];
    } emptyDlg;
    memset(&emptyDlg, 0, sizeof(emptyDlg));
    GetCreateWinInfo(dummyWndClass);
#endif
    emptyDlg.header.style = _styleBits;
    _hWnd = CreateDialogIndirect(owner->GetInstance(),
                     &emptyDlg.header,
                     parent->GetHWND(),
                     (DLGPROC)owner->GetWndProcPtr(PApplication::DlgProcType));
    PAssert(_hWnd != NULL, PInvalidWindow);
  }

  _styleBits = GetWindowLong(_hWnd, GWL_STYLE);
  _exStyleBits = GetWindowLong(_hWnd, GWL_EXSTYLE);

  owner->AddWindowHandle(_hWnd, this);
  owner->AddDialog(this);
}


void PInteractorLayout::WndProc()
{
  PInteractor::WndProc();

  switch (_msg->event) {
    case WM_CLOSE :
      DestroyWindow(_hWnd);
      break;

    case WM_DESTROY :
      owner->RemoveDialog(this);
      handledDestroySignal.Signal();
      break;
  }

  handledMessageSignal.Signal();
}


void PInteractorLayout::DefWndProc()
{
  _msg->processed = FALSE;
}


///////////////////////////////////////////////////////////////////////////////
// PDialog

PDialog::PDialog(PInteractor * parent)
  : PInteractorLayout(parent)
{
  backgroundColour = owner->GetButtonBkColour();
}


PDialog::PDialog(PInteractor * parent, PRESOURCE_ID resID)
  : PInteractorLayout(parent, resID)
{
  backgroundColour = owner->GetButtonBkColour();
}


void PDialog::WndProc()
{
  if (_msg->event == WM_CLOSE)
    OnCancel();
  else
    PInteractor::WndProc();
}


void PDialog::GetCreateWinInfo(WNDCLASS & wndClass)
{
  PInteractorLayout::GetCreateWinInfo(wndClass);
  _styleBits = WS_POPUP|WS_CLIPCHILDREN|WS_CAPTION|WS_SYSMENU|WS_BORDER;
}


///////////////////////////////////////////////////////////////////////////////
// PFloatingDialog

void PFloatingDialog::Construct()
{
  titleFont = PRealFont(PFont("MS Sans Serif", 1));  // Smallest font possible
  borderWidth = owner->GetBorderSize().Width();
  borderHeight = owner->GetBorderSize().Height();
  titleHeight = titleFont.GetHeight(TRUE) + borderHeight*2;
}


void PFloatingDialog::WndProc()
{
  switch (_msg->event) {
    case WM_NCCALCSIZE :
      NCCalcSize((LPNCCALCSIZE_PARAMS)_msg->lParam);
      return;
    
    case WM_NCHITTEST :
      _msg->lResult = NCHitTest(_msg->lParam);
      return;

    case WM_NCPAINT :
      NCPaint();
      return;
  }
  PDialog::WndProc();
}


void PFloatingDialog::NCCalcSize(LPNCCALCSIZE_PARAMS cs)
{
  PDim bdr = owner->GetBorderSize();
  cs->rgrc[0].top += titleHeight + borderHeight;
  cs->rgrc[0].left += borderWidth;
  cs->rgrc[0].bottom -= borderHeight;
  cs->rgrc[0].right -= borderWidth;
}


LRESULT PFloatingDialog::NCHitTest(const PPoint & pt)
{
  PRect rect;
  GetWindowRect(_hWnd, rect);
  rect.Inflate(-(PORDINATE)borderWidth, -(PORDINATE)borderHeight);

  if (!rect.ContainsPoint(pt))
    return HTBORDER;

  if (pt.Y() > rect.Y() + (PORDINATE)titleHeight)
    return HTCLIENT;

  if (pt.X() < rect.X() + (PORDINATE)titleHeight)
    return HTSYSMENU;

  return HTCAPTION;
}


void PFloatingDialog::NCPaint()
{
  PDrawCanvas canvas(this, GetWindowDC(_hWnd), TRUE, TRUE);

  PRect rect;
  GetWindowRect(_hWnd, rect);
  rect.SetOrigin(0, 0);

⌨️ 快捷键说明

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