dialogs.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:38k
源码类别:

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * dialogs.cxx
  3.  *
  4.  * Dialog classes implementation.
  5.  *
  6.  * Portable Windows Library
  7.  *
  8.  * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
  9.  *
  10.  * The contents of this file are subject to the Mozilla Public License
  11.  * Version 1.0 (the "License"); you may not use this file except in
  12.  * compliance with the License. You may obtain a copy of the License at
  13.  * http://www.mozilla.org/MPL/
  14.  *
  15.  * Software distributed under the License is distributed on an "AS IS"
  16.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  17.  * the License for the specific language governing rights and limitations
  18.  * under the License.
  19.  *
  20.  * The Original Code is Portable Windows Library.
  21.  *
  22.  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
  23.  *
  24.  * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
  25.  * All Rights Reserved.
  26.  *
  27.  * Contributor(s): ______________________________________.
  28.  *
  29.  * $Log: dialogs.cxx,v $
  30.  * Revision 1.66  2000/04/04 22:26:20  robertj
  31.  * Fixed bug in PDialog when close button closes regardless of OnCancel() virtual.
  32.  *
  33.  * Revision 1.65  2000/03/17 20:32:22  robertj
  34.  * Fixed race conditions in mult-threaded windows (dialogs in particular)
  35.  *
  36.  * Revision 1.64  2000/03/04 13:08:35  robertj
  37.  * Moved common function in open file dialog to common source file.
  38.  *
  39.  * Revision 1.63  2000/03/04 10:09:38  robertj
  40.  * Fixed bugs in open file dialog (showed up in Win2K).
  41.  *
  42.  * Revision 1.62  1999/11/16 06:51:42  robertj
  43.  * Created PCustomListBox to allow motif native code PStringListBox implementation
  44.  *
  45.  * Revision 1.61  1999/11/01 00:07:44  robertj
  46.  * Changed semantics of OnClose() to be the same as PTitledWindow
  47.  *
  48.  * Revision 1.60  1999/10/24 11:52:05  robertj
  49.  * Fixed problems with creating/deleting dialogs from background threads.
  50.  *
  51.  * Revision 1.59  1999/08/25 05:13:33  robertj
  52.  * Fixed problem with calling modal dialog from a background thread.
  53.  *
  54.  * Revision 1.58  1999/08/07 07:13:23  robertj
  55.  * Fixed problems with "balloon help" text popup.
  56.  *
  57.  * Revision 1.57  1999/02/16 08:08:07  robertj
  58.  * MSVC 6.0 compatibility changes.
  59.  *
  60.  * Revision 1.56  1998/12/12 00:43:51  robertj
  61.  * Added functions for user request on printing selection only.
  62.  * Fixed transfer of start and end pages from PPrintDialog.
  63.  *
  64.  * Revision 1.55  1998/12/02 03:50:12  robertj
  65.  * Unix compatibility changes
  66.  *
  67.  * Revision 1.54  1998/09/24 03:42:39  robertj
  68.  * Added open software license.
  69.  *
  70.  * Revision 1.53  1998/09/24 01:55:32  robertj
  71.  * Fixed bug that caused modal dialog not to go away when closed from another thread.
  72.  *
  73.  * Revision 1.52  1998/09/22 15:09:45  robertj
  74.  * Fixed confusion in Font Dialog, variable at different levels with same name.
  75.  * Fixed Font Dialog not returning font that was selected.
  76.  *
  77.  * Revision 1.51  1998/09/17 04:25:56  robertj
  78.  * Fixed race condition if dialog is closed by a different thread to the PProcess thrad.
  79.  *
  80.  * Revision 1.50  1998/09/14 13:14:20  robertj
  81.  * Fixed memory leak on delete of PStringList, not deleting all its contents.
  82.  * Fixed failure to update control values on non-modal dialog box initialisation.
  83.  *
  84.  * Revision 1.49  1998/09/04 07:01:06  robertj
  85.  * Added a lot of DEVMODE infor for win95 to propagate from PrintDlg to PPrintCanvas.
  86.  *
  87.  * Revision 1.48  1998/03/20 03:12:44  robertj
  88.  * Fixed bug in standard file dialog getting filename and folder.
  89.  *
  90.  * Revision 1.47  1998/03/09 07:14:31  robertj
  91.  * Explorer based OpenDirDialog.
  92.  * More implementation of file type lists.
  93.  *
  94.  * Revision 1.46  1998/03/09 01:46:45  robertj
  95.  * Enhanced file types for standard file dialog.
  96.  *
  97.  * Revision 1.44  1996/11/04 03:32:25  robertj
  98.  * Fixed bug in background colour of dialogs.
  99.  *
  100.  * Revision 1.43  1996/10/31 12:39:56  robertj
  101.  * Added RCS keywords.
  102.  *
  103.  */
  104. #include <pwlib.h>
  105. class PDummyListBox : public PListBox
  106. {
  107.   PCLASSINFO(PDummyListBox, PListBox)
  108.   public:
  109.     PDummyListBox(PInteractorLayout * layout, PRESOURCE_ID ctrlID)
  110.       : PListBox(layout, ctrlID, PNotifier(), NULL) { }
  111.     virtual void OnDrawEntry(PINDEX, PObject &, PCanvas &, const PRect &, BOOL, BOOL)
  112.       { }
  113.     virtual PDim OnMeasureEntry(PINDEX, PObject &, PCanvas &)
  114.       { return PDim(); }
  115.     virtual BOOL IsOwnerDraw() const
  116.       { return FALSE; }
  117. };
  118. #define new PNEW
  119. ///////////////////////////////////////////////////////////////////////////////
  120. // PInteractorLayout
  121. PInteractorLayout::PInteractorLayout(PInteractor * parent)
  122.   : PInteractor(parent)
  123. {
  124.   focusInteractor = this;
  125.   pResourceID = (PRESOURCE_ID)-1;
  126. }
  127. PInteractorLayout::PInteractorLayout(PInteractor * parent, PRESOURCE_ID resID)
  128.   : PInteractor(parent)
  129. {
  130.   focusInteractor = this;
  131.   pResourceID = resID;
  132. }
  133. PInteractorLayout::~PInteractorLayout()
  134. {
  135.   if (_hWnd != NULL && PThread::Current() != owner) {
  136.     if (_hWnd != P_DEAD_WINDOW)
  137.       PostMessage(_hWnd, WM_CLOSE, 0, 0);
  138.     handledDestroySignal.Wait();
  139.   }
  140.   owner->RemoveDialog(this);
  141. }
  142. BOOL PEXPORTED EnumDlgChildren(HWND hWnd, PInteractorLayout * layout)
  143. {
  144.   if (GetParent(hWnd) != layout->GetHWND())
  145.     return TRUE;
  146.   PRESOURCE_ID ctrlID = (PRESOURCE_ID)GetDlgCtrlID(hWnd);
  147.   if (ctrlID == 0xffff)
  148.     return TRUE;
  149.   if (layout->GetControl(ctrlID) != NULL)
  150.     return TRUE;
  151.   PControl * child = NULL;
  152.   char className[20];
  153.   GetClassName(hWnd, className, sizeof(className));
  154.   DWORD style = GetWindowLong(hWnd, GWL_STYLE);
  155.   if (lstrcmpi(className, "EDIT") == 0) {
  156.     if ((style&ES_MULTILINE) != 0)
  157.       child = new PMultiLineEditBox(layout, ctrlID, PNotifier(), NULL);
  158.     else {
  159.       char str[30];
  160.       GetWindowText(hWnd, str, sizeof(str));
  161.       SetWindowText(hWnd, "");
  162.       if (lstrcmpi(str, "INTEDIT") == 0)
  163.         child = new PIntegerEditBox(layout, ctrlID, PNotifier(), NULL);
  164.       else if (lstrcmpi(str, "REALEDIT") == 0)
  165.         child = new PFloatEditBox(layout, ctrlID, PNotifier(), NULL);
  166.       else
  167.         child = new PEditBox(layout, ctrlID, PNotifier(), NULL);
  168.     }
  169.   }
  170.   else if (lstrcmpi(className, "STATIC") == 0) {
  171.     switch (style&15) {
  172.       case SS_LEFT :
  173.       case SS_SIMPLE :
  174.       case SS_LEFTNOWORDWRAP :
  175.       case SS_CENTER :
  176.       case SS_RIGHT :
  177.         child = new PStaticText(layout, ctrlID, PNotifier(), NULL);
  178.         break;
  179.       case SS_ICON :
  180.         child = new PStaticIcon(layout, ctrlID, PNotifier(), NULL);
  181.         break;
  182.     }
  183.   }
  184.   else if (lstrcmpi(className, "BUTTON") == 0) {
  185.     switch (style&15) {
  186.       case BS_PUSHBUTTON :
  187.       case BS_DEFPUSHBUTTON :
  188.         child = new PTextButton(layout, ctrlID, PNotifier(), NULL);
  189.         break;
  190.       case BS_AUTOCHECKBOX :
  191.       case BS_CHECKBOX :
  192.         child = new PCheckBox(layout, ctrlID, PNotifier(), NULL);
  193.         break;
  194.       case BS_AUTO3STATE :
  195.       case BS_3STATE :
  196.         child = new PCheck3WayBox(layout, ctrlID, PNotifier(), NULL);
  197.         break;
  198.       case BS_AUTORADIOBUTTON :
  199.       case BS_RADIOBUTTON :
  200.         child = new PRadioButton(layout, ctrlID, PNotifier(), NULL);
  201.         break;
  202.       case BS_GROUPBOX :
  203.         child = new PStaticBox(layout, ctrlID, PNotifier(), NULL);
  204.         break;
  205.     }
  206.   }
  207.   else if (lstrcmpi(className, "LISTBOX") == 0) {
  208.     if ((style&LBS_OWNERDRAWVARIABLE) == 0)
  209.       child = new PDummyListBox(layout, ctrlID);
  210.     else
  211.       child = new PStringListBox(layout, ctrlID, PNotifier(), NULL);
  212.   }
  213.   else if (lstrcmpi(className, "COMBOBOX") == 0) {
  214.     switch (style&15) {
  215.       case CBS_DROPDOWN :
  216.         child = new PChoiceBox(layout, ctrlID, PNotifier(), NULL);
  217.         break;
  218.       case CBS_DROPDOWNLIST :
  219.         child = new PComboBox(layout, ctrlID, PNotifier(), NULL);
  220.         break;
  221.     }
  222.   }
  223.   else if (lstrcmpi(className, "SCROLLBAR") == 0) {
  224.     if ((style&1) != 0)
  225.       child = new PVerticalScrollBar(layout, ctrlID, PNotifier(), NULL);
  226.     else
  227.       child = new PHorizontalScrollBar(layout, ctrlID, PNotifier(), NULL);
  228.   }
  229.   return TRUE;
  230. }
  231. void PInteractorLayout::ConstructEnd(PRESOURCE_ID resID)
  232. {
  233.   EnumChildWindows(GetHWND(), (WNDENUMPROC)EnumDlgChildren, (LPARAM)this);
  234.   PResourceData dialog("#5", resID);
  235.   PResourceData strings("DIALOGSTRINGS", resID);
  236. #if defined(_WIN32)
  237.   PINDEX numControls = ((const DLGTEMPLATE *)(const BYTE *)dialog)->cdit;
  238.   const WORD * strptr = (const WORD *)(const BYTE *)strings;
  239.   const WORD * strbase;
  240. #else
  241.   PINDEX numControls = dialog[4];
  242.   const char * strptr = (const char *)(const BYTE *)strings;
  243.   const char * strbase;
  244. #endif
  245.   for (PINDEX i = 0; i < numControls; i++) {
  246.     PControl & child = (PControl &)children[i];
  247.     strbase = strptr;
  248.     PINDEX len = 0;
  249.     while (*strptr++ != 0)
  250.       len++;
  251.     if (len != 0)
  252.       child.SetBalloonHelp(PString(strbase, len));
  253.     while (*strptr != 0) {
  254.       strbase = strptr;
  255.       len = 0;
  256.       while (*strptr++ != 0)
  257.         len++;
  258.       if (child.IsDescendant(PChoiceBox::Class()))
  259.         ((PChoiceBox&)child).AddString(PString(strbase, len));
  260.       else if (child.IsDescendant(PStringListBox::Class()))
  261.         ((PStringListBox&)child).AddString(PString(strbase, len));
  262.       else if (child.IsDescendant(PComboBox::Class()))
  263.         ((PComboBox&)child).AddString(PString(strbase, len));
  264.     }
  265.     strptr++;
  266.   }
  267.   for (i = 1; i < GetNumChildren(); i++) {
  268.     if (children[i].IsDescendant(PRadioButton::Class()) &&
  269.                              children[i-1].IsDescendant(PRadioButton::Class()))
  270.       ((PRadioButton &)children[i]).AddToGroup((PRadioButton &)children[i-1]);
  271.   }
  272.   UpdateControls();
  273. }
  274. void PInteractorLayout::GetCreateWinInfo(WNDCLASS & wndClass)
  275. {
  276.   PInteractor::GetCreateWinInfo(wndClass);
  277.   wndClass.lpszClassName = "Dialog";
  278. }
  279. void PInteractorLayout::CreateHWND()
  280. {
  281.   if (pResourceID != -1) {
  282.     _hWnd = CreateDialog(owner->GetInstance(),
  283.                      MAKEINTRESOURCE(pResourceID),
  284.                      parent->GetHWND(),
  285.                      (DLGPROC)owner->GetWndProcPtr(PApplication::DlgProcType));
  286.     PAssert(_hWnd != NULL, PInvalidWindow);
  287.     PPoint pos = GetPosition(ScreenCoords);
  288.     if (pos.X() < 0 && pos.Y() < 0)
  289.       SetPosition(0,0,CentreParent,CentreParent);
  290.     HFONT hFont = (HFONT)(UINT)SendMessage(_hWnd, WM_GETFONT, 0, 0L);
  291.     if (hFont != NULL)
  292.       font = PRealFont(hFont);
  293.     else
  294.       SetFont(parent->GetFont(), TRUE);
  295.   }
  296.   else {
  297.     WNDCLASS dummyWndClass;
  298. #if defined(_WIN32)
  299.     struct {
  300.       DLGTEMPLATE header;
  301.       WORD  szMenuName[1], szClassName[1], szCaption[1];
  302.       WORD  wPointSize;
  303.       WORD  szFaceName[1];
  304.     } emptyDlg;
  305.     memset(&emptyDlg, 0, sizeof(emptyDlg));
  306.     GetCreateWinInfo(dummyWndClass);
  307.     emptyDlg.header.dwExtendedStyle = _exStyleBits;
  308. #else
  309.     struct {
  310.       struct {
  311.         DWORD style;
  312.         BYTE  bNumberOfItems;
  313.         WORD  x, y, cx, cy;
  314.       } header;
  315.       char  szMenuName[1], szClassName[1], szCaption[1];
  316.       WORD  wPointSize;
  317.       char  szFaceName[1];
  318.     } emptyDlg;
  319.     memset(&emptyDlg, 0, sizeof(emptyDlg));
  320.     GetCreateWinInfo(dummyWndClass);
  321. #endif
  322.     emptyDlg.header.style = _styleBits;
  323.     _hWnd = CreateDialogIndirect(owner->GetInstance(),
  324.                      &emptyDlg.header,
  325.                      parent->GetHWND(),
  326.                      (DLGPROC)owner->GetWndProcPtr(PApplication::DlgProcType));
  327.     PAssert(_hWnd != NULL, PInvalidWindow);
  328.   }
  329.   _styleBits = GetWindowLong(_hWnd, GWL_STYLE);
  330.   _exStyleBits = GetWindowLong(_hWnd, GWL_EXSTYLE);
  331.   owner->AddWindowHandle(_hWnd, this);
  332.   owner->AddDialog(this);
  333. }
  334. void PInteractorLayout::WndProc()
  335. {
  336.   PInteractor::WndProc();
  337.   switch (_msg->event) {
  338.     case WM_CLOSE :
  339.       DestroyWindow(_hWnd);
  340.       break;
  341.     case WM_DESTROY :
  342.       owner->RemoveDialog(this);
  343.       handledDestroySignal.Signal();
  344.       break;
  345.   }
  346.   handledMessageSignal.Signal();
  347. }
  348. void PInteractorLayout::DefWndProc()
  349. {
  350.   _msg->processed = FALSE;
  351. }
  352. ///////////////////////////////////////////////////////////////////////////////
  353. // PDialog
  354. PDialog::PDialog(PInteractor * parent)
  355.   : PInteractorLayout(parent)
  356. {
  357.   backgroundColour = owner->GetButtonBkColour();
  358. }
  359. PDialog::PDialog(PInteractor * parent, PRESOURCE_ID resID)
  360.   : PInteractorLayout(parent, resID)
  361. {
  362.   backgroundColour = owner->GetButtonBkColour();
  363. }
  364. void PDialog::WndProc()
  365. {
  366.   if (_msg->event == WM_CLOSE)
  367.     OnCancel();
  368.   else
  369.     PInteractor::WndProc();
  370. }
  371. void PDialog::GetCreateWinInfo(WNDCLASS & wndClass)
  372. {
  373.   PInteractorLayout::GetCreateWinInfo(wndClass);
  374.   _styleBits = WS_POPUP|WS_CLIPCHILDREN|WS_CAPTION|WS_SYSMENU|WS_BORDER;
  375. }
  376. ///////////////////////////////////////////////////////////////////////////////
  377. // PFloatingDialog
  378. void PFloatingDialog::Construct()
  379. {
  380.   titleFont = PRealFont(PFont("MS Sans Serif", 1));  // Smallest font possible
  381.   borderWidth = owner->GetBorderSize().Width();
  382.   borderHeight = owner->GetBorderSize().Height();
  383.   titleHeight = titleFont.GetHeight(TRUE) + borderHeight*2;
  384. }
  385. void PFloatingDialog::WndProc()
  386. {
  387.   switch (_msg->event) {
  388.     case WM_NCCALCSIZE :
  389.       NCCalcSize((LPNCCALCSIZE_PARAMS)_msg->lParam);
  390.       return;
  391.     
  392.     case WM_NCHITTEST :
  393.       _msg->lResult = NCHitTest(_msg->lParam);
  394.       return;
  395.     case WM_NCPAINT :
  396.       NCPaint();
  397.       return;
  398.   }
  399.   PDialog::WndProc();
  400. }
  401. void PFloatingDialog::NCCalcSize(LPNCCALCSIZE_PARAMS cs)
  402. {
  403.   PDim bdr = owner->GetBorderSize();
  404.   cs->rgrc[0].top += titleHeight + borderHeight;
  405.   cs->rgrc[0].left += borderWidth;
  406.   cs->rgrc[0].bottom -= borderHeight;
  407.   cs->rgrc[0].right -= borderWidth;
  408. }
  409. LRESULT PFloatingDialog::NCHitTest(const PPoint & pt)
  410. {
  411.   PRect rect;
  412.   GetWindowRect(_hWnd, rect);
  413.   rect.Inflate(-(PORDINATE)borderWidth, -(PORDINATE)borderHeight);
  414.   if (!rect.ContainsPoint(pt))
  415.     return HTBORDER;
  416.   if (pt.Y() > rect.Y() + (PORDINATE)titleHeight)
  417.     return HTCLIENT;
  418.   if (pt.X() < rect.X() + (PORDINATE)titleHeight)
  419.     return HTSYSMENU;
  420.   return HTCAPTION;
  421. }
  422. void PFloatingDialog::NCPaint()
  423. {
  424.   PDrawCanvas canvas(this, GetWindowDC(_hWnd), TRUE, TRUE);
  425.   PRect rect;
  426.   GetWindowRect(_hWnd, rect);
  427.   rect.SetOrigin(0, 0);
  428.   PColour bdrcol;
  429.   bdrcol.FromSYSCOLOR(COLOR_WINDOWFRAME);
  430.   canvas.SetPenFgColour(bdrcol);
  431.   canvas.SetFillFgColour(PColour::Clear);
  432.   canvas.DrawRect(rect);
  433.   rect.SetHeight(titleHeight+borderHeight);
  434.   canvas.SetFillFgColour(owner->GetActiveTitleBkColour());
  435.   canvas.FillRect(rect);
  436.   PString title = GetTitle();
  437.   canvas.SetTextFgColour(owner->GetActiveTitleFgColour());
  438.   canvas.SetTextBkColour(owner->GetActiveTitleBkColour());
  439.   canvas.SetFont(titleFont);
  440.   canvas.DrawTextLine(rect.X() + titleHeight,
  441.                       rect.Y() + borderHeight, title, NULL, title.GetLength());
  442.   rect.SetWidth(titleHeight);
  443.   rect.Inflate(-(int)borderWidth*2, -(int)borderHeight*2);
  444.   canvas.SetFillFgColour(owner->GetButtonBkColour());
  445.   canvas.DrawBevelledRect(rect, TRUE, FALSE);
  446. }
  447. void PFloatingDialog::GetCreateWinInfo(WNDCLASS & wndClass)
  448. {
  449.   PDialog::GetCreateWinInfo(wndClass);
  450.   _styleBits = WS_POPUP|WS_CLIPCHILDREN|WS_BORDER|WS_SYSMENU;
  451.   _exStyleBits |= WS_EX_TOPMOST;
  452. }
  453. ///////////////////////////////////////////////////////////////////////////////
  454. // PModalDialog
  455. PModalDialog::~PModalDialog()
  456. {
  457. }
  458. void PModalDialog::Construct()
  459. {
  460.   ok = cancel = NULL;
  461.   runState = Initialising;
  462. }
  463. int PModalDialog::RunModal()
  464. {
  465.   runState = Running;
  466.   owner->GetWindow()->Disable();
  467.   OnInit();
  468.   Show();
  469.   if (PThread::Current() == owner) {
  470.     while (runState == Running && owner->ProcessMessage())
  471.       ;
  472.   }
  473.   else {
  474.     while (runState == Running)
  475.       handledMessageSignal.Wait();
  476.   }
  477.   return returnValue;
  478. }
  479. void PModalDialog::EndModal(int retVal)
  480. {
  481.   owner->GetWindow()->Enable();
  482.   Hide();
  483.   returnValue = retVal;
  484.   runState = Ended;
  485.   PostMessage(_hWnd, WM_COMMAND, 0, 0);
  486. }
  487. void PModalDialog::GetCreateWinInfo(WNDCLASS & wndClass)
  488. {
  489.   PDialog::GetCreateWinInfo(wndClass);
  490.   _styleBits |= DS_MODALFRAME;
  491.   _exStyleBits |= WS_EX_DLGMODALFRAME;
  492. }
  493. void PModalDialog::InitStandardDialog()
  494. {
  495. //  EnumChildWindows(_hWnd, (WNDENUMPROC)EnumDlgChildren, (LPARAM)this);
  496.   font = PRealFont((HFONT)(UINT)SendMessage(_hWnd, WM_GETFONT, 0, 0L));
  497.   HDC hDC = GetDC(_hWnd);
  498.   HBRUSH hBrush = (HBRUSH)(UINT)SendMessage(_hWnd,
  499. #ifdef _WIN32
  500.                       WM_CTLCOLORDLG, (WPARAM)hDC, (LPARAM)_hWnd);
  501. #else
  502.                       WM_CTLCOLOR, (WPARAM)hDC, MAKELONG(_hWnd, CTLCOLOR_DLG));
  503. #endif
  504.   ReleaseDC(_hWnd, hDC);
  505.   if (hBrush == NULL)
  506.     hBrush = (HBRUSH)PGET_CLASS_VALUE(_hWnd, HBRBACKGROUND);
  507.   if (hBrush != NULL) {
  508.     LOGBRUSH brush;
  509.     GetObject(hBrush, sizeof(brush), (LPSTR)&brush);
  510.     backgroundColour.FromCOLORREF(brush.lbColor);
  511.   }
  512.   runState = Running;
  513.   _styleBits = GetWindowLong(_hWnd, GWL_STYLE) | WS_CLIPSIBLINGS;
  514.   SetWindowLong(_hWnd, GWL_STYLE, _styleBits);
  515.   _exStyleBits = GetWindowLong(_hWnd, GWL_EXSTYLE);
  516.   OnInit();
  517. }
  518. ///////////////////////////////////////////////////////////////////////////////
  519. // PFileDialog
  520. #if !defined(_WIN32)
  521. typedef UINT (CALLBACK * LPOFNHOOKPROC)(HWND, UINT, WPARAM, LPARAM);
  522. #endif
  523. PFileDialog::PFileDialog(PInteractor * parent, PRESOURCE_ID resID)
  524.   : PModalDialog(parent, resID)
  525. {
  526.   selChangeMessage = RegisterWindowMessage(LBSELCHSTRING);
  527.   memset(&fileDlgInfo, 0, sizeof(fileDlgInfo));
  528.   fileDlgInfo.lStructSize = sizeof(fileDlgInfo);
  529.   fileDlgInfo.hwndOwner = parent->GetHWND();
  530.   fileDlgInfo.hInstance = owner->GetInstance();
  531.   fileBuffer[0] = '';
  532.   fileDlgInfo.lpstrFile = fileBuffer;
  533.   strcpy(customFilter, "All Files");
  534.   memcpy(&customFilter[strlen(customFilter)+1], "*.*", 5);
  535.   fileDlgInfo.lpstrCustomFilter = customFilter;
  536.   fileDlgInfo.nMaxCustFilter = sizeof(customFilter);
  537.   fileDlgInfo.nMaxFile = sizeof(fileBuffer);
  538. #ifdef OFN_EXPLORER
  539.   fileDlgInfo.Flags = OFN_ENABLEHOOK|OFN_HIDEREADONLY|OFN_NOVALIDATE|OFN_EXPLORER;
  540. #else
  541.   fileDlgInfo.Flags = OFN_ENABLEHOOK|OFN_HIDEREADONLY|OFN_NOVALIDATE;
  542. #endif
  543.   fileDlgInfo.lCustData = (DWORD)this;
  544.   fileDlgInfo.lpfnHook =
  545.             (LPOFNHOOKPROC)owner->GetWndProcPtr(PApplication::FileDlgProcType);
  546. }
  547. PFileDialog::~PFileDialog()
  548. {
  549.   if (_hWnd != P_DEAD_WINDOW)
  550.     DestroyWindow(_hWnd);
  551. }
  552. void PFileDialog::SetTitle(const PString & title)
  553. {
  554.   if (_hWnd != NULL)
  555.     PModalDialog::SetTitle(title);
  556.   else {
  557.     dlgTitle = title;
  558.     fileDlgInfo.lpstrTitle = dlgTitle;
  559.   }
  560. }
  561. void PFileDialog::WndProc()
  562. {
  563.   switch (_msg->event) {
  564.     case WM_INITDIALOG :
  565.       InitStandardDialog();
  566.       return;
  567. #ifndef OFN_EXPLORER
  568.     case WM_COMMAND :
  569.       switch (LOWORD(_msg->wParam)) {
  570.         case IDOK : {
  571.           directory = PDirectory();
  572.           GetDlgItemText(_hWnd, 1152, fileBuffer, sizeof(fileBuffer));
  573.           file = PFilePath(fileBuffer);
  574.           OnOk();
  575.           return;
  576.         }
  577.         case IDCANCEL :
  578.           OnCancel();
  579.           return;
  580.       }
  581.       break;
  582. #endif
  583.     case WM_NOTIFY:
  584.       {
  585.         OFNOTIFY * ofNotify = (OFNOTIFY *)_msg->lParam;
  586.         HWND hDlg = ::GetParent(_hWnd);
  587.         switch (ofNotify->hdr.code) {
  588.           case CDN_FILEOK :
  589.             SendMessage(hDlg, CDM_GETFOLDERPATH, sizeof(fileBuffer), (LPARAM)fileBuffer);
  590.             directory = fileBuffer;
  591.             SendMessage(hDlg, CDM_GETFILEPATH,   sizeof(fileBuffer), (LPARAM)fileBuffer);
  592.             file = PFilePath(fileBuffer);
  593.             OnOk();
  594.             return;
  595.         }
  596.       }
  597.       break;
  598.     default:
  599.       if (_msg->event == selChangeMessage)
  600.         OnListSelection(_msg->wParam, LOWORD(_msg->lParam), HIWORD(_msg->lParam));
  601.   }
  602.   PModalDialog::WndProc();
  603. }
  604. void PFileDialog::OnOk()
  605. {
  606.   DefWndProc();
  607. }
  608. void PFileDialog::OnCancel()
  609. {
  610.   DefWndProc();
  611. }
  612. void PFileDialog::OnListSelection(UINT, UINT, UINT)
  613. {
  614. }
  615. void PFileDialog::CreateHWND()
  616. {
  617.   PAssertAlways("Illegal operation on PFileDialog");
  618. }
  619. ///////////////////////////////////////////////////////////////////////////////
  620. // POpenFileDialog
  621. POpenFileDialog::POpenFileDialog(PInteractor * parent, PRESOURCE_ID resID)
  622.   : PFileDialog(parent, resID)
  623. {
  624.   fileDlgInfo.Flags |= OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT;
  625.   if (resID != PSTD_ID_DIALOG_OPEN_FILE) {
  626.     fileDlgInfo.Flags |= OFN_ENABLETEMPLATE;
  627.     fileDlgInfo.lpTemplateName = MAKEINTRESOURCE(resID);
  628.   }
  629. }
  630. int POpenFileDialog::RunModal()
  631. {
  632.   fileDlgInfo.lpstrInitialDir = directory;
  633.   lstrcpy(fileBuffer, defaultFilename);
  634.   PString fileTypeStr;
  635.   if (fileTypes.GetSize() != 0) {
  636.     for (PINDEX i = 0; i < fileTypes.GetSize(); i++) {
  637.       PString s = fileTypes[i];
  638.       if (s.Find('377') != P_MAX_INDEX)
  639.         fileTypeStr += s + "377";
  640.       else {
  641.         PString tmp("*");
  642.         tmp += s + "377";
  643.         fileTypeStr += tmp + tmp;
  644.       }
  645.     }
  646.     fileTypeStr += "377";
  647.     fileDlgInfo.lpstrFilter = fileTypeStr;
  648.     for (LPSTR p = (LPSTR)fileDlgInfo.lpstrFilter; *p != ''; p++) {
  649.       while (*p == '377')
  650.         *p++ = '';
  651.     }
  652.     fileDlgInfo.nFilterIndex = 1;
  653.   }
  654.   if (GetOpenFileName(&fileDlgInfo)) {
  655.     runState = Ended;
  656.     return TRUE;
  657.   }
  658.   DWORD err = CommDlgExtendedError();
  659. #if defined(_WIN32)
  660.   SetLastError(err);
  661. #endif
  662.   PAssertOS(err == 0);
  663.   return FALSE;
  664. }
  665. void POpenFileDialog::SetFileTypes(const PStringArray & array)
  666. {
  667.   fileTypes = array;
  668.   SetInitialFileType(GetFinalFileType());
  669. }
  670. void POpenFileDialog::SetInitialFileType(PINDEX i)
  671. {
  672.   if (i != P_MAX_INDEX)
  673.     fileDlgInfo.nFilterIndex = i+1;
  674.   else
  675.     fileDlgInfo.nFilterIndex = 0;
  676. }
  677. void POpenFileDialog::SetInitialFileType(const PString & str)
  678. {
  679.   memset(customFilter, 0, sizeof(customFilter));
  680.   strncpy(customFilter, str, sizeof(customFilter)-1);
  681.   fileDlgInfo.nFilterIndex = 0;
  682. }
  683. PINDEX POpenFileDialog::GetFinalFileType() const
  684. {
  685.   if (fileDlgInfo.nFilterIndex > 0)
  686.     return fileDlgInfo.nFilterIndex-1;
  687.   return P_MAX_INDEX;
  688. }
  689. BOOL POpenFileDialog::GetFinalFileType(PString & str) const
  690. {
  691.   if ((PINDEX)fileDlgInfo.nFilterIndex > fileTypes.GetSize())
  692.     return FALSE;
  693.   if (fileDlgInfo.nFilterIndex > 0)
  694.     str = fileTypes[fileDlgInfo.nFilterIndex-1];
  695.   else
  696.     str = &customFilter[strlen(customFilter)+1];
  697.   return !str;
  698. }
  699. void POpenFileDialog::FilterFilesFromList()
  700. {
  701.   PINDEX i = 0;
  702.   while (i < (PINDEX)SendDlgItemMessage(_hWnd, 1120, LB_GETCOUNT, 0, 0)) {
  703.     char str[P_MAX_PATH];
  704.     SendDlgItemMessage(_hWnd, 1120, LB_GETTEXT, i, (DWORD)str);
  705.     if (OnFilterFile(str))
  706.       i++;
  707.     else
  708.       SendDlgItemMessage(_hWnd, 1120, LB_DELETESTRING, i, 0);
  709.   }
  710. }
  711. void POpenFileDialog::OnListSelection(UINT listBox, UINT item, UINT operation)
  712. {
  713.   if (listBox == 1120 && operation == CD_LBSELCHANGE) {
  714.     char str[P_MAX_PATH];
  715.     SendDlgItemMessage(_hWnd, 1120, LB_GETTEXT, item, (DWORD)str);
  716.     OnFileSelect(str);
  717.   }
  718.   else if (listBox == 1121 && !fileTypes.IsEmpty())
  719.     FilterFilesFromList();
  720. }
  721. void POpenFileDialog::WndProc()
  722. {
  723.   PFileDialog::WndProc();
  724.   switch (_msg->event) {
  725.     case WM_INITDIALOG :
  726.       FilterFilesFromList();
  727.       break;
  728.     case WM_COMMAND :
  729.       if (LOWORD(_msg->wParam) == IDOK)
  730.         FilterFilesFromList();
  731.       break;
  732.   }
  733. }
  734. ///////////////////////////////////////////////////////////////////////////////
  735. // PSaveFileDialog
  736. PSaveFileDialog::PSaveFileDialog(PInteractor * parent, PRESOURCE_ID resID)
  737.   : PFileDialog(parent, resID)
  738. {
  739.   fileDlgInfo.Flags |= OFN_CREATEPROMPT;
  740.   if (resID != PSTD_ID_DIALOG_SAVE_FILE) {
  741.     fileDlgInfo.Flags |= OFN_ENABLETEMPLATE;
  742.     fileDlgInfo.lpTemplateName = MAKEINTRESOURCE(resID);
  743.   }
  744. }
  745. int PSaveFileDialog::RunModal()
  746. {
  747.   fileDlgInfo.lpstrInitialDir = directory;
  748.   lstrcpy(fileBuffer, defaultFilename);
  749.   if (GetSaveFileName(&fileDlgInfo)) {
  750.     runState = Ended;
  751.     return TRUE;
  752.   }
  753.   DWORD err = CommDlgExtendedError();
  754. #if defined(_WIN32)
  755.   SetLastError(err);
  756. #endif
  757.   PAssertOS(err == 0);
  758.   return FALSE;
  759. }
  760. ///////////////////////////////////////////////////////////////////////////////
  761. // POpenDirDialog
  762. POpenDirDialog::POpenDirDialog(PInteractor * parent, PRESOURCE_ID resID)
  763.   : PFileDialog(parent, resID)
  764. {
  765. #ifdef OFN_EXPLORER
  766.   fileDlgInfo.lpstrFilter = "~~a.ridiculous.extensionA ridiculous extension";
  767.   lstrcpy(fileBuffer, "~~a.ridiculous.filename~~");
  768.   if (resID != PSTD_ID_DIALOG_OPEN_DIR) {
  769.     fileDlgInfo.Flags |= OFN_ENABLETEMPLATE;
  770.     fileDlgInfo.lpTemplateName = MAKEINTRESOURCE(resID);
  771.   }
  772. #else
  773.   fileDlgInfo.Flags |= OFN_ENABLETEMPLATE;
  774.   fileDlgInfo.lpTemplateName = MAKEINTRESOURCE(resID);
  775. #endif
  776. }
  777. int POpenDirDialog::RunModal()
  778. {
  779.   fileDlgInfo.lpstrInitialDir = directory;
  780.   if (GetOpenFileName(&fileDlgInfo)) {
  781.     runState = Ended;
  782.     return TRUE;
  783.   }
  784.   DWORD err = CommDlgExtendedError();
  785. #if defined(_WIN32)
  786.   SetLastError(err);
  787. #endif
  788.   PAssertOS(err == 0);
  789.   return FALSE;
  790. }
  791. void POpenDirDialog::WndProc()
  792. {
  793.   switch (_msg->event) {
  794.     case WM_INITDIALOG :
  795. #ifdef OFN_EXPLORER
  796.       {
  797.         HWND dlgWnd = ::GetParent(_hWnd);
  798.         ShowWindow(GetDlgItem(dlgWnd, 0x441), SW_HIDE);
  799.         ShowWindow(GetDlgItem(dlgWnd, 0x470), SW_HIDE);
  800.         ShowWindow(GetDlgItem(dlgWnd, 0x442), SW_HIDE);
  801.         ShowWindow(GetDlgItem(dlgWnd, 0x480), SW_HIDE);
  802.       }
  803. #else
  804.       SetDlgItemText(_hWnd, 1159, PDirectory());
  805. #endif
  806.       break;
  807. #ifndef OFN_EXPLORER
  808.     case WM_COMMAND :
  809.       if (LOWORD(_msg->wParam) == IDOK) {
  810.         GetDlgItemText(dlgWnd, 1159, fileBuffer, sizeof(fileBuffer));
  811.         directory = PDirectory(fileBuffer);
  812.         SetDlgItemText(dlgWnd, 1152, "xxxxxxxx.xxx");
  813.       }
  814. #endif
  815.   }
  816.   PFileDialog::WndProc();
  817. }
  818. void POpenDirDialog::OnListSelection(UINT, UINT, UINT)
  819. {
  820. #ifndef OFN_EXPLORER
  821.   char str[P_MAX_PATH];
  822.   GetDlgItemText(_hWnd, 1088, str, sizeof(str));
  823.   SetDlgItemText(_hWnd, 1159, str);
  824. #endif
  825. }
  826. ///////////////////////////////////////////////////////////////////////////////
  827. // PPrintDialog
  828. #if !defined(_WIN32)
  829. typedef UINT (CALLBACK * LPPRINTHOOKPROC)(HWND, UINT, WPARAM, LPARAM);
  830. #endif
  831. void PPrintDialog::Construct()
  832. {
  833.   memset(&printDlgInfo, 0, sizeof(printDlgInfo));
  834.   printDlgInfo.hInstance = owner->GetInstance();
  835.   printDlgInfo.lStructSize = sizeof(printDlgInfo);
  836.   printDlgInfo.hwndOwner = GetParent()->GetHWND();
  837.   printDlgInfo.lpfnPrintHook =
  838.          (LPPRINTHOOKPROC)owner->GetWndProcPtr(PApplication::PrintDlgProcType);
  839.   printDlgInfo.lCustData = (DWORD)this;
  840.   printDlgInfo.Flags = PD_ENABLEPRINTHOOK;
  841.   printDlgInfo.hDevMode = printInfo.GetHDEVMODE();
  842.   printDlgInfo.hDevNames = printInfo.GetDevNames();
  843.   if (printInfo.GetStartPage() == 0)
  844.     printDlgInfo.Flags |= PD_NOPAGENUMS;
  845.   else {
  846.     printDlgInfo.nFromPage = (WORD)printInfo.GetStartPage();
  847.     printDlgInfo.nToPage = (WORD)printInfo.GetEndPage();
  848.   }
  849.   switch (printInfo.GetSelectionOnly()) {
  850.     case PPrintInfo::NoSelectionOnly :
  851.       printDlgInfo.Flags |= PD_NOSELECTION;
  852.       break;
  853.     case PPrintInfo::SelectionOnlyOn :
  854.       printDlgInfo.Flags |= PD_SELECTION;
  855.       break;
  856.     default :
  857.       break;
  858.   }
  859.   printDlgInfo.nCopies = (WORD)printInfo.GetCopies();
  860. }
  861. PPrintDialog::~PPrintDialog()
  862. {
  863.   if (_hWnd != P_DEAD_WINDOW)
  864.     DestroyWindow(_hWnd);
  865.   if (printDlgInfo.hDevMode != NULL)
  866.     GlobalFree(printDlgInfo.hDevMode);
  867.   if (printDlgInfo.hDevNames != NULL)
  868.     GlobalFree(printDlgInfo.hDevNames);
  869.   if (printDlgInfo.hDC != NULL)
  870.     DeleteDC(printDlgInfo.hDC);
  871. }
  872. void PPrintDialog::SetTitle(const PString & title)
  873. {
  874.   if (_hWnd != NULL)
  875.     PModalDialog::SetTitle(title);
  876.   else
  877.     dlgTitle = title;
  878. }
  879. int PPrintDialog::RunModal()
  880. {
  881.   if (PrintDlg(&printDlgInfo)) {
  882.     runState = Ended;
  883.     return TRUE;
  884.   }
  885.   DWORD err = CommDlgExtendedError();
  886. #if defined(_WIN32)
  887.   SetLastError(err);
  888. #endif
  889.   PAssertOS(err == 0);
  890.   return FALSE;
  891. }
  892. void PPrintDialog::WndProc()
  893. {
  894.   switch (_msg->event) {
  895.     case WM_INITDIALOG :
  896.       if (!dlgTitle.IsEmpty())
  897.         SetWindowText(_hWnd, dlgTitle);
  898.       InitStandardDialog();
  899.       return;
  900.     case WM_COMMAND :
  901.       switch (LOWORD(_msg->wParam)) {
  902.         case IDOK : {
  903.           OnOk();
  904.           return;
  905.         }
  906.         case IDCANCEL :
  907.           OnCancel();
  908.           return;
  909.       }
  910.   }
  911.   PModalDialog::WndProc();
  912. }
  913. void PPrintDialog::OnOk()
  914. {
  915.   printInfo.SetFromPrintDlg(printDlgInfo);
  916.   DefWndProc();
  917. }
  918. void PPrintDialog::OnCancel()
  919. {
  920.   DefWndProc();
  921. }
  922. void PPrintDialog::CreateHWND()
  923. {
  924.   PAssertAlways("Illegal operation on Print Dialog");
  925. }
  926. ///////////////////////////////////////////////////////////////////////////////
  927. // PPrinterSetupDialog
  928. void PPrinterSetupDialog::Construct()
  929. {
  930.   printDlgInfo.Flags |= PD_PRINTSETUP;
  931.   if (pResourceID != PSTD_ID_DIALOG_PRINTER_SETUP) {
  932.     printDlgInfo.Flags |= PD_ENABLEPRINTTEMPLATE;
  933.     printDlgInfo.lpSetupTemplateName = MAKEINTRESOURCE(pResourceID);
  934.   }
  935. }
  936. ///////////////////////////////////////////////////////////////////////////////
  937. // PPrintJobDialog
  938. void PPrintJobDialog::Construct()
  939. {
  940.   if (pResourceID != PSTD_ID_DIALOG_PRINT_JOB) {
  941.     printDlgInfo.Flags |= PD_ENABLEPRINTTEMPLATE;
  942.     printDlgInfo.lpPrintTemplateName = MAKEINTRESOURCE(pResourceID);
  943.   }
  944. }
  945. ///////////////////////////////////////////////////////////////////////////////
  946. // PFontDialog
  947. #if !defined(_WIN32)
  948. typedef UINT (CALLBACK * LPCFHOOKPROC)(HWND, UINT, WPARAM, LPARAM);
  949. #endif
  950. void PFontDialog::Construct(PRESOURCE_ID)
  951. {
  952.   memset(&fontDlgInfo, 0, sizeof(fontDlgInfo));
  953.   fontDlgInfo.lStructSize = sizeof(fontDlgInfo);
  954.   fontDlgInfo.hInstance = owner->GetInstance();
  955.   fontDlgInfo.hwndOwner = GetParent()->GetHWND();
  956.   fontDlgInfo.lpLogFont = &logFont;
  957.   fontDlgInfo.lpfnHook =
  958.              (LPCFHOOKPROC)owner->GetWndProcPtr(PApplication::FontDlgProcType);
  959.   fontDlgInfo.lCustData = (DWORD)this;
  960.   fontDlgInfo.Flags = CF_ANSIONLY|CF_EFFECTS|CF_INITTOLOGFONTSTRUCT|CF_ENABLEHOOK;
  961.   if (printerCanvas == NULL)
  962.     fontDlgInfo.Flags |= CF_SCREENFONTS;
  963.   else {
  964.     fontDlgInfo.Flags |= CF_PRINTERFONTS;
  965.     fontDlgInfo.hDC = printerCanvas->GetHDC();
  966.   }
  967.   if (pResourceID != PSTD_ID_DIALOG_FONT) {
  968.     fontDlgInfo.Flags |= CF_ENABLETEMPLATE;
  969.     fontDlgInfo.lpTemplateName = MAKEINTRESOURCE(pResourceID);
  970.   }
  971.   SetDefaultFont(selectedFont);
  972. }
  973. PFontDialog::~PFontDialog()
  974. {
  975.   if (_hWnd != P_DEAD_WINDOW)
  976.     DestroyWindow(_hWnd);
  977. }
  978. void PFontDialog::SetTitle(const PString & title)
  979. {
  980.   if (_hWnd != NULL)
  981.     PModalDialog::SetTitle(title);
  982.   else
  983.     dlgTitle = title;
  984. }
  985. void PFontDialog::SetDefaultFont(const PFont & font)
  986. {
  987.   if (runState != Initialising)
  988.     return;
  989.   selectedFont = font;
  990.   memset(&logFont, 0, sizeof(logFont));
  991.   if (printerCanvas != NULL)
  992.     logFont.lfHeight = printerCanvas->FromPointsY(font.GetSize());
  993.   else {
  994.     PDrawCanvas canvas(parent, TRUE);
  995.     logFont.lfHeight = canvas.FromPointsY(font.GetSize());
  996.   }
  997.   logFont.lfWeight = font.IsBold() ? FW_BOLD : FW_NORMAL;
  998.   logFont.lfItalic = (BYTE)font.IsItalic();
  999.   logFont.lfUnderline = (BYTE)font.IsUnderlined();
  1000.   strncpy(logFont.lfFaceName, font.GetFacename(), LF_FACESIZE-1);
  1001. }
  1002. int PFontDialog::RunModal()
  1003. {
  1004.   if (ChooseFont(&fontDlgInfo)) {
  1005.     runState = Ended;
  1006.     return TRUE;
  1007.   }
  1008.   DWORD err = CommDlgExtendedError();
  1009. #if defined(_WIN32)
  1010.   SetLastError(err);
  1011. #endif
  1012.   PAssertOS(err == 0);
  1013.   return FALSE;
  1014. }
  1015. void PFontDialog::WndProc()
  1016. {
  1017.   switch (_msg->event) {
  1018.     case WM_INITDIALOG :
  1019.       if (!dlgTitle.IsEmpty())
  1020.         SetWindowText(_hWnd, dlgTitle);
  1021.       InitStandardDialog();
  1022.       return;
  1023.     case WM_COMMAND :
  1024.       switch (LOWORD(_msg->wParam)) {
  1025.         case IDOK : {
  1026.           SendMessage(_hWnd, WM_CHOOSEFONT_GETLOGFONT, 0, (DWORD)&logFont);
  1027.           PDIMENSION size = PABS(logFont.lfHeight);
  1028.           if (printerCanvas != NULL)
  1029.             size = printerCanvas->ToPointsY(size);
  1030.           else {
  1031.             PDrawCanvas canvas(parent, TRUE);
  1032.             size = canvas.ToPointsY(size);
  1033.           }
  1034.           WORD styles = PFont::Regular;
  1035.           if (logFont.lfWeight > FW_NORMAL)
  1036.             styles |= PFont::Bold;
  1037.           if (logFont.lfItalic)
  1038.             styles |= PFont::Italic;
  1039.           if (logFont.lfUnderline)
  1040.             styles |= PFont::Underline;
  1041.           selectedFont = PFont(logFont.lfFaceName, size, styles);
  1042.           OnOk();
  1043.           return;
  1044.         }
  1045.         case IDCANCEL :
  1046.           OnCancel();
  1047.           return;
  1048.       }
  1049.   }
  1050.   PModalDialog::WndProc();
  1051. }
  1052. void PFontDialog::OnOk()
  1053. {
  1054.   DefWndProc();
  1055. }
  1056. void PFontDialog::OnCancel()
  1057. {
  1058.   DefWndProc();
  1059. }
  1060. void PFontDialog::CreateHWND()
  1061. {
  1062.   PAssertAlways("Illegal operation on Print Dialog");
  1063. }
  1064. ///////////////////////////////////////////////////////////////////////////////
  1065. // PColourDialog
  1066. #if !defined(_WIN32)
  1067. typedef UINT (CALLBACK * LPCCHOOKPROC)(HWND, UINT, WPARAM, LPARAM);
  1068. #endif
  1069. void PColourDialog::Construct(PRESOURCE_ID)
  1070. {
  1071.   PConfig cfg("CONTROL.INI", "Custom Colors");
  1072.   for (PINDEX i = 0; i < NumCustomColours; i++)
  1073.     customColours[i] = cfg.GetString(psprintf("Color%c", i+'A')).AsInteger(16);
  1074.   memset(&colourDlgInfo, 0, sizeof(colourDlgInfo));
  1075.   colourDlgInfo.lStructSize = sizeof(colourDlgInfo);
  1076.   colourDlgInfo.hInstance = (HWND)owner->GetInstance();
  1077.   colourDlgInfo.hwndOwner = GetParent()->GetHWND();
  1078.   colourDlgInfo.lpfnHook =
  1079.            (LPCCHOOKPROC)owner->GetWndProcPtr(PApplication::ColourDlgProcType);
  1080.   colourDlgInfo.rgbResult = colour.ToCOLORREF();
  1081.   colourDlgInfo.lpCustColors = customColours;
  1082.   colourDlgInfo.lCustData = (DWORD)this;
  1083.   colourDlgInfo.Flags = CC_RGBINIT|CC_ENABLEHOOK;
  1084.   if (pResourceID != PSTD_ID_DIALOG_COLOUR) {
  1085.     colourDlgInfo.Flags |= CC_ENABLETEMPLATE;
  1086.     colourDlgInfo.lpTemplateName = MAKEINTRESOURCE(pResourceID);
  1087.   }
  1088. }
  1089. PColourDialog::~PColourDialog()
  1090. {
  1091.   if (_hWnd != P_DEAD_WINDOW)
  1092.     DestroyWindow(_hWnd);
  1093. }
  1094. void PColourDialog::SetTitle(const PString & title)
  1095. {
  1096.   if (_hWnd != NULL)
  1097.     PModalDialog::SetTitle(title);
  1098.   else
  1099.     dlgTitle = title;
  1100. }
  1101. void PColourDialog::SetColour(const PColour & col)
  1102. {
  1103.   if (runState == Initialising)
  1104.     colour = col;
  1105. }
  1106. int PColourDialog::RunModal()
  1107. {
  1108.   if (ChooseColor(&colourDlgInfo)) {
  1109.     runState = Ended;
  1110.     colour.FromCOLORREF(colourDlgInfo.rgbResult);
  1111.     return TRUE;
  1112.   }
  1113.   DWORD err = CommDlgExtendedError();
  1114. #if defined(_WIN32)
  1115.   SetLastError(err);
  1116. #endif
  1117.   PAssertOS(err == 0);
  1118.   return FALSE;
  1119. }
  1120. void PColourDialog::WndProc()
  1121. {
  1122.   switch (_msg->event) {
  1123.     case WM_INITDIALOG :
  1124.       if (!dlgTitle.IsEmpty())
  1125.         SetWindowText(_hWnd, dlgTitle);
  1126.       InitStandardDialog();
  1127.       return;
  1128.     case WM_COMMAND :
  1129.       switch (LOWORD(_msg->wParam)) {
  1130.         case IDOK : {
  1131.           OnOk();
  1132.           return;
  1133.         }
  1134.         case IDCANCEL :
  1135.           OnCancel();
  1136.           return;
  1137.       }
  1138.   }
  1139.   PModalDialog::WndProc();
  1140. }
  1141. void PColourDialog::OnOk()
  1142. {
  1143.   DefWndProc();
  1144. }
  1145. void PColourDialog::OnCancel()
  1146. {
  1147.   DefWndProc();
  1148. }
  1149. void PColourDialog::CreateHWND()
  1150. {
  1151.   PAssertAlways("Illegal operation on Print Dialog");
  1152. }
  1153. ///////////////////////////////////////////////////////////////////////////////
  1154. // PApplication
  1155. BOOL PApplication::DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
  1156. {
  1157.   if (msg == WM_INITDIALOG)
  1158.     ShowWindow(hWnd, SW_HIDE);
  1159.   PInteractor * window = (PInteractor *)createdWindows.GetAt((HWNDKey)hWnd);
  1160.   if (window == NULL)
  1161.     return FALSE;
  1162.   PInteractor::_WindowsMessage message;
  1163.   message.event = msg;
  1164.   message.wParam = wParam;
  1165.   message.lParam = lParam;
  1166.   message.lResult = 0;
  1167.   message.processed = TRUE;
  1168.   PInteractor::_WindowsMessage * oldMessage = window->_msg;
  1169.   window->_msg = &message;
  1170.   window->WndProc();
  1171.   window->_msg = oldMessage;
  1172.   if (message.processed) {
  1173.     switch (msg) {
  1174. #ifdef WIN32
  1175.       case WM_CTLCOLORBTN :
  1176.       case WM_CTLCOLORDLG :
  1177.       case WM_CTLCOLOREDIT :
  1178.       case WM_CTLCOLORLISTBOX :
  1179.       case WM_CTLCOLORMSGBOX :
  1180.       case WM_CTLCOLORSCROLLBAR :
  1181.       case WM_CTLCOLORSTATIC :
  1182. #else
  1183.       case WM_CTLCOLOR :
  1184. #endif
  1185.       case WM_COMPAREITEM :
  1186.       case WM_VKEYTOITEM :
  1187.       case WM_CHARTOITEM :
  1188.       case WM_QUERYDRAGICON :
  1189.         return (UINT)message.lResult;
  1190.     }
  1191.     SetWindowLong(hWnd, DWL_MSGRESULT, message.lResult);
  1192.   }
  1193.   return message.processed;
  1194. }
  1195. BOOL PApplication::FileDlgProc(HWND hWnd,
  1196.                                         UINT msg, WPARAM wParam, LPARAM lParam)
  1197. {
  1198.   if (msg == WM_INITDIALOG) {
  1199.     PInteractor * window = (PInteractor *)((LPOPENFILENAME)lParam)->lCustData;
  1200.     PAssert(window != NULL, PLogicError);
  1201.     AddWindowHandle(hWnd, window);
  1202.     window->_hWnd = hWnd;
  1203.   }
  1204.   return DlgProc(hWnd, msg, wParam, lParam);
  1205. }
  1206. BOOL PApplication::PrintDlgProc(HWND hWnd,
  1207.                                         UINT msg, WPARAM wParam, LPARAM lParam)
  1208. {
  1209.   if (msg == WM_INITDIALOG) {
  1210.     PInteractor * window = (PInteractor *)((LPPRINTDLG)lParam)->lCustData;
  1211.     PAssert(window != NULL, PLogicError);
  1212.     AddWindowHandle(hWnd, window);
  1213.     window->_hWnd = hWnd;
  1214.   }
  1215.   return DlgProc(hWnd, msg, wParam, lParam);
  1216. }
  1217. BOOL PApplication::FontDlgProc(HWND hWnd,
  1218.                                         UINT msg, WPARAM wParam, LPARAM lParam)
  1219. {
  1220.   if (msg == WM_INITDIALOG) {
  1221.     PInteractor * window = (PInteractor *)((LPCHOOSEFONT)lParam)->lCustData;
  1222.     PAssert(window != NULL, PLogicError);
  1223.     AddWindowHandle(hWnd, window);
  1224.     window->_hWnd = hWnd;
  1225.   }
  1226.   return DlgProc(hWnd, msg, wParam, lParam);
  1227. }
  1228. BOOL PApplication::ColourDlgProc(HWND hWnd,
  1229.                                         UINT msg, WPARAM wParam, LPARAM lParam)
  1230. {
  1231.   if (msg == WM_INITDIALOG) {
  1232.     PInteractor * window = (PInteractor *)((LPCHOOSECOLOR)lParam)->lCustData;
  1233.     PAssert(window != NULL, PLogicError);
  1234.     AddWindowHandle(hWnd, window);
  1235.     window->_hWnd = hWnd;
  1236.   }
  1237.   return DlgProc(hWnd, msg, wParam, lParam);
  1238. }
  1239. // End Of File ///////////////////////////////////////////////////////////////