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

IP电话/视频会议

开发平台:

Visual C++

  1. /*
  2.  * controls.cxx
  3.  *
  4.  * Control interactor classes implmentation.
  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: controls.cxx,v $
  30.  * Revision 1.63  2000/07/11 19:01:36  robertj
  31.  * Fix of resizing PMultiLineEditBox allowing for scroll bars etc.
  32.  *
  33.  * Revision 1.62  2000/07/11 18:24:03  robertj
  34.  * Fixed incorrect return value on PComboBox::GetCurrent() when no selection.
  35.  *
  36.  * Revision 1.61  2000/06/27 00:14:53  robertj
  37.  * Fixed bug that causes crash when gettng cursor/selection position.
  38.  *
  39.  * Revision 1.60  2000/04/13 23:18:42  robertj
  40.  * Fixed problems with sizing controls with scroll bars.
  41.  *
  42.  * Revision 1.59  2000/04/13 01:37:14  robertj
  43.  * Added missing implementation of PEditBox::GetSelection() on Win32.
  44.  * Added PEditBox::ReplaceSelection() function.
  45.  *
  46.  * Revision 1.58  1999/11/23 05:24:32  robertj
  47.  * Moved function from platform independent to platform dependent files.
  48.  *
  49.  * Revision 1.57  1999/11/16 06:51:42  robertj
  50.  * Created PCustomListBox to allow motif native code PStringListBox implementation
  51.  *
  52.  * Revision 1.56  1998/09/24 03:42:36  robertj
  53.  * Added open software license.
  54.  *
  55.  * Revision 1.55  1998/09/21 13:31:01  robertj
  56.  * Changes to support new PListView class. Different call back method.
  57.  *
  58.  * Revision 1.54  1998/09/14 14:57:46  robertj
  59.  * Fixed incorrect return of owner draw mode for PStringListBox class.
  60.  *
  61.  * Revision 1.53  1998/09/14 13:11:14  robertj
  62.  * Fixed memory leak on delete of PStringList, not deleting all its contents.
  63.  * Added tab stops to string list box.
  64.  *
  65.  * Revision 1.52  1998/09/07 14:02:32  robertj
  66.  * Fixed double delete of PStrings in PStringListBix descendents.
  67.  *
  68.  * Revision 1.51  1998/09/03 15:48:34  robertj
  69.  * Added missing vertical scroll bar on drop down boxes.
  70.  *
  71.  * Revision 1.50  1998/08/06 00:55:59  robertj
  72.  * Fixed using non-standard controls as PControl descendants.
  73.  *
  74.  * Revision 1.49  1998/05/07 05:22:11  robertj
  75.  * Fixed bug in colour setting of radio buttons from resource.
  76.  *
  77.  * Revision 1.48  1998/02/06 04:00:17  robertj
  78.  * Fixed colour of controls, again!
  79.  *
  80.  * Revision 1.47  1998/01/26 00:20:04  robertj
  81.  * Fixed colour of static controls in windows and dialogs.
  82.  *
  83.  * Revision 1.46  1995/11/20 11:07:20  robertj
  84.  * Fixed bug in scroll bar colour.
  85.  * Fixed bug causing double notification in scroll bar click.
  86.  *
  87.  * Revision 1.45  1995/11/09 12:29:56  robertj
  88.  * Moved window style bits to member variable.
  89.  *
  90.  * Revision 1.44  1995/08/24 12:43:52  robertj
  91.  * Function OnEndInput() moved to platform dependent code.
  92.  *
  93.  * Revision 1.43  1995/07/02 06:23:32  robertj
  94.  * Fixed mouse button events not appearing in static text controls.
  95.  * Fixed bug with creating right and centred static text controls being left aligned.
  96.  *
  97.  * Revision 1.42  1995/06/17 11:10:02  robertj
  98.  * Added function to determine if control is a tab stop.
  99.  *
  100.  * Revision 1.41  1995/06/04 12:52:15  robertj
  101.  * Fixed bug in assert of list box resource control.
  102.  *
  103.  * Revision 1.40  1995/04/25 11:44:05  robertj
  104.  * Fixed Borland compiler warnings.
  105.  *
  106.  * Revision 1.39  1995/04/02 09:28:05  robertj
  107.  * Added "balloon" help.
  108.  *
  109.  * Revision 1.38  1995/03/12 05:00:24  robertj
  110.  * Re-organisation of DOS/WIN16 and WIN32 platforms to maximise common code.
  111.  * Used built-in equate for WIN32 API (_WIN32).
  112.  *
  113.  * Revision 1.37  1995/02/19  04:16:31  robertj
  114.  * Added callback when PListBox::SetSelection changes selection.
  115.  * Added dynamically linked command processing.
  116.  *
  117.  * Revision 1.36  1995/02/05  00:57:21  robertj
  118.  * Had to change variable name "small" for MSVC 2.0
  119.  *
  120.  * Revision 1.35  1995/01/28  07:28:49  robertj
  121.  * Assured all Windows strings have n converted to rn and vice versa.
  122.  *
  123.  * Revision 1.34  1995/01/27  11:29:21  robertj
  124.  * Fixed numerous bugs.
  125.  * Fixed bug in nested messages.
  126.  * Underscored library variables.
  127.  *
  128.  */
  129. #include <pwlib.h>
  130. #include <math.h>
  131. static char ControlResourceMismatch[] = "Control class mismatch from resource";
  132. //////////////////////////////////////////////////////////////////////////////
  133. // PControl
  134. PControl::PControl(PInteractor * parent, const PNotifier & notify, void *valuePtr)
  135.   : PInteractor(PAssertNULL(parent)),
  136.     callback(notify)
  137. {
  138.   PAssert(_hWnd == NULL, PLogicError);
  139.   notifyForStateUpdate = FALSE;
  140.   valuePointer = valuePtr;
  141.   PRESOURCE_ID id = (PRESOURCE_ID)(parent->GetNumChildren() + 100);
  142.   if (parent->IsDescendant(PInteractorLayout::Class())) {
  143.     while (((PInteractorLayout*)parent)->GetControl(id))
  144.       id++;
  145.   }
  146.   controlID = id;
  147. }
  148. PControl::PControl(PInteractorLayout * parent,
  149.                  PRESOURCE_ID ctlID, const PNotifier & notify, void * valuePtr)
  150.   : PInteractor(parent, GetDlgItem(PAssertNULL(parent)->GetHWND(), ctlID)),
  151.     callback(notify)
  152. {
  153.   PAssert(_hWnd != NULL, "GetDlgItem() failed.");
  154.   notifyForStateUpdate = FALSE;
  155.   valuePointer = valuePtr;
  156.   controlID = ctlID;
  157.   _styleBits = GetWindowLong(_hWnd, GWL_STYLE);
  158.   _exStyleBits = GetWindowLong(_hWnd, GWL_EXSTYLE);
  159.   SubClassControlWndProc();
  160. }
  161. BOOL PControl::IsTabStop() const
  162. {
  163.   return (_styleBits&WS_TABSTOP) != 0;
  164. }
  165. void PControl::CreateHWND()
  166. {
  167.   HINSTANCE hInst = owner->GetInstance();
  168.   WNDCLASS wclass;
  169.   GetCreateWinInfo(wclass);
  170.   if (!GetClassInfo(hInst, wclass.lpszClassName, &wclass))
  171.     PAssertOS(RegisterClass(&wclass));
  172.   _hWnd = CreateWindow(wclass.lpszClassName,
  173.                        "",
  174.                        _styleBits,
  175.                        -100, -100,
  176.                        10, 10,
  177.                        parent->GetHWND(),
  178.                        (HMENU)(controlID),
  179.                        hInst,
  180.                        NULL);
  181.   owner->AddWindowHandle(PAssertNULL(_hWnd), this);
  182.   SubClassControlWndProc();
  183.   SetWndFont();
  184. }
  185. void PControl::SubClassControlWndProc()
  186. {
  187.   wndProc = (WNDPROC)GetWindowLong(_hWnd, GWL_WNDPROC);
  188.   WNDPROC pwlibWndProc = owner->GetWndProcPtr(PApplication::WndProcType);
  189.   if (wndProc != pwlibWndProc)
  190.     SetWindowLong(_hWnd, GWL_WNDPROC, (DWORD)pwlibWndProc);
  191.   else
  192.     wndProc = NULL;
  193. #ifdef _WIN32
  194.   SetClassLong(_hWnd, GCL_STYLE, GetClassLong(_hWnd, GCL_STYLE)|CS_DBLCLKS);
  195. #else
  196.   SetClassWord(_hWnd, GCW_STYLE, GetClassWord(_hWnd, GCW_STYLE)|CS_DBLCLKS);
  197. #endif
  198. }
  199. void PControl::SetControlID(PRESOURCE_ID ID)
  200. {
  201.   controlID = ID;
  202.   PSET_WINDOW_VALUE(GetHWND(), ID, controlID);
  203. }
  204. void PControl::DefWndProc()
  205. {
  206.   if (wndProc == NULL)
  207.     PInteractor::DefWndProc();
  208.   else {
  209.     _msg->lResult =
  210.          CallWindowProc(wndProc, _hWnd, _msg->event, _msg->wParam, _msg->lParam);
  211.     _msg->processed = TRUE;
  212.   }
  213. }
  214. int PControl::TranslateOption(NMHDR &) const
  215. {
  216.   return -1;
  217. }
  218. //////////////////////////////////////////////////////////////////////////////
  219. // PNamedControl
  220. PNamedControl::PNamedControl(PInteractor * parent,
  221.            const PString & newName, const PNotifier & notify, void * valuePtr)
  222.   : PControl(parent, notify, valuePtr), initName(newName)
  223. {
  224. }
  225. void PNamedControl::SetName(const PString & name)
  226. {
  227.   SendMessage(GetHWND(), WM_SETREDRAW, FALSE, 0L);
  228.   SetWndText(name);
  229.   SendMessage(_hWnd, WM_SETREDRAW, TRUE, 0L);
  230.   InvalidateRect(_hWnd, NULL, TRUE);
  231.   UpdateWindow(_hWnd);
  232. }
  233. void PNamedControl::CreateHWND()
  234. {
  235.   PControl::CreateHWND();
  236.   SetName(initName);
  237. }
  238. void PNamedControl::GetCreateWinInfo(WNDCLASS & wndClass)
  239. {
  240.   PControl::GetCreateWinInfo(wndClass);
  241.   wndClass.lpszClassName = "Button";
  242.   _styleBits |= WS_TABSTOP;
  243. }
  244. //////////////////////////////////////////////////////////////////////////////
  245. // PStaticText
  246. PStaticText::PStaticText(PInteractorLayout * parent,
  247.                 PRESOURCE_ID ctlID, const PNotifier & notify, void * valuePtr)
  248.   : PNamedControl(parent, ctlID, notify, valuePtr)
  249. {
  250.   switch (_styleBits&15) {
  251.     case SS_LEFT :
  252.     case SS_SIMPLE :
  253.     case SS_LEFTNOWORDWRAP :
  254.       alignment = PCanvas::LeftAlign;
  255.       break;
  256.     case SS_CENTER :
  257.       alignment = PCanvas::Centred;
  258.       break;
  259.     case SS_RIGHT :
  260.       alignment = PCanvas::RightAlign;
  261.       break;
  262.     default:
  263.       PAssertAlways(ControlResourceMismatch);
  264.   }
  265.   foregroundColour = parent->GetForegroundColour();
  266.   backgroundColour = parent->GetBackgroundColour();
  267. }
  268. void PStaticText::SetAlignment(int newAlign)
  269. {
  270.   if (alignment != newAlign) {
  271.     alignment = newAlign;
  272.     _styleBits &= ~15;
  273.     switch (alignment&PCanvas::HorizontalAlignmentMask) {
  274.       case PCanvas::LeftAlign :
  275.         _styleBits |= SS_LEFT;
  276.         break;
  277.       case PCanvas::Centred :
  278.         _styleBits |= SS_CENTER;
  279.         break;
  280.       case PCanvas::RightAlign :
  281.         _styleBits |= SS_RIGHT;
  282.     }
  283.     SetWindowLong(_hWnd, GWL_STYLE, _styleBits);
  284.     Invalidate();
  285.   }
  286. }
  287. void PStaticText::GetCreateWinInfo(WNDCLASS & wndClass)
  288. {
  289.   PNamedControl::GetCreateWinInfo(wndClass);
  290.   wndClass.lpszClassName = "Static";
  291.   switch (alignment&PCanvas::HorizontalAlignmentMask) {
  292.     case PCanvas::RightAlign :
  293.       _styleBits |= SS_RIGHT;
  294.       break;
  295.     case PCanvas::Centred :
  296.       _styleBits |= SS_CENTER;
  297.       break;
  298.     default :
  299.       _styleBits |= SS_LEFT;
  300.   }
  301. }
  302. void PStaticText::OnRedraw(PCanvas & canvas)
  303. {
  304.   if (canvas.NullHDC() &&
  305.               (alignment&PCanvas::VerticalAlignmentMask) == PCanvas::TopAlign)
  306.     PControl::OnRedraw(canvas);
  307.   else
  308.     canvas.DrawString(canvas.GetDrawingBounds(), GetName(), alignment);
  309. }
  310. void PStaticText::WndProc()
  311. {
  312.   if (_msg->event == WM_NCHITTEST)
  313.     _msg->lResult = HTCLIENT;
  314.   else
  315.     PNamedControl::WndProc();
  316. }
  317. //////////////////////////////////////////////////////////////////////////////
  318. // PEditBox
  319. void PEditBox::SetText(const PString & name)
  320. {
  321.   SetWndText(name);
  322.   parent->OnControlNotify(*this, EditChange);
  323. }
  324. BOOL PEditBox::GetSelection(PINDEX * start, PINDEX * finish) const
  325. {
  326.   PINDEX dummyStart;
  327.   if (start == NULL)
  328.     start = &dummyStart;
  329.   PINDEX dummyFinish;
  330.   if (finish == NULL)
  331.     finish = &dummyFinish;
  332.   SendMessage(GetHWND(), EM_GETSEL, (WPARAM)start, (LPARAM)finish);
  333.   return *finish > *start;
  334. }
  335. int PEditBox::TranslateOption(NMHDR & msg) const
  336. {
  337.   return msg.code == EN_CHANGE ? NotifyChange : -1;
  338. }
  339. void PEditBox::GetCreateWinInfo(WNDCLASS & wndClass)
  340. {
  341.   PControl::GetCreateWinInfo(wndClass);
  342.   wndClass.lpszClassName = "Edit";
  343.   _styleBits |= WS_BORDER|WS_TABSTOP|ES_AUTOHSCROLL;
  344. }
  345. //////////////////////////////////////////////////////////////////////////////
  346. // PPasswordEditBox
  347. PPasswordEditBox::PPasswordEditBox(PInteractorLayout * parent,
  348.               PRESOURCE_ID ctlID, const PNotifier & notify, PString * valuePtr)
  349.   : PEditBox(parent, ctlID, notify, valuePtr)
  350. {
  351.   PAssert((_styleBits&ES_PASSWORD) != 0, ControlResourceMismatch);
  352. }
  353. void PPasswordEditBox::GetCreateWinInfo(WNDCLASS & wndClass)
  354. {
  355.   PEditBox::GetCreateWinInfo(wndClass);
  356.   _styleBits |= ES_PASSWORD;
  357. }
  358. //////////////////////////////////////////////////////////////////////////////
  359. // PMultiLineEditBox
  360. PMultiLineEditBox::PMultiLineEditBox(PInteractorLayout * parent,
  361.               PRESOURCE_ID ctlID, const PNotifier & notify, PString * valuePtr)
  362.   : PEditBox(parent, ctlID, notify, valuePtr)
  363. {
  364.   PAssert((_styleBits&ES_MULTILINE) != 0, ControlResourceMismatch);
  365. }
  366. void PMultiLineEditBox::GetCreateWinInfo(WNDCLASS & wndClass)
  367. {
  368.   PEditBox::GetCreateWinInfo(wndClass);
  369.   _styleBits |= WS_VSCROLL|WS_HSCROLL|ES_AUTOVSCROLL|ES_MULTILINE|ES_WANTRETURN;
  370. }
  371. void PMultiLineEditBox::_SetDimensions(PDIMENSION width, PDIMENSION height,
  372.                                  CoordinateSystem coords)
  373. {
  374.   GetHWND();
  375.   if (coords == LocalCoords) {
  376.     width = ToPixelsDX(width);
  377.     height = ToPixelsDY(height);
  378.   }
  379.   SetWindowPos(_hWnd, NULL, 0, 0, width, height, SWP_NOMOVE|SWP_NOZORDER);
  380. }
  381. //////////////////////////////////////////////////////////////////////////////
  382. // PIntegerEditBox
  383. PIntegerEditBox::PIntegerEditBox(PInteractorLayout * parent,
  384.                  PRESOURCE_ID ctlID, const PNotifier & notify, long * valuePtr)
  385.   : PNumberEditBox(parent, ctlID, notify, valuePtr)
  386. {
  387.   PStringArray limits = GetWndText().Tokenise(" ");
  388.   SetWndText("");
  389.   PAssert(limits.GetSize() > 1 && limits[0] == "INTEDITBOX", ControlResourceMismatch);
  390.   minimum = limits.GetSize() < 2 ? LONG_MIN : limits[1].AsInteger();
  391.   maximum = limits.GetSize() < 3 ? LONG_MAX : limits[2].AsInteger();
  392.   nudge   = limits.GetSize() < 4 ? 1 : limits[3].AsInteger();
  393.   base    = (BYTE)(limits.GetSize() < 5 ? 1 : limits[4].AsInteger());
  394.   PAssert(base >= 2 && base <= 36, PInvalidParameter);
  395. }
  396. //////////////////////////////////////////////////////////////////////////////
  397. // PFloatEditBox
  398. PFloatEditBox::PFloatEditBox(PInteractorLayout * parent,
  399.                PRESOURCE_ID ctlID, const PNotifier & notify, double * valuePtr)
  400.   : PNumberEditBox(parent, ctlID, notify, valuePtr)
  401. {
  402.   PStringArray limits = GetWndText().Tokenise(" ");
  403.   SetWndText("");
  404.   PAssert(limits.GetSize() > 1 && limits[0] == "FLOATEDITBOX", ControlResourceMismatch);
  405.   minimum  = limits.GetSize() < 2 ? -HUGE_VAL : limits[1].AsReal();
  406.   maximum  = limits.GetSize() < 3 ?  HUGE_VAL : limits[2].AsReal();
  407.   nudge    = limits.GetSize() < 4 ? 1 : limits[3].AsReal();
  408.   decimals = limits.GetSize() < 5 ? 1 : (int)limits[4].AsInteger();
  409. }
  410. //////////////////////////////////////////////////////////////////////////////
  411. // PPushButton
  412. PPushButton::PPushButton(PInteractorLayout * parent,
  413.                 PRESOURCE_ID ctlID, const PNotifier & notify, void * valuePtr)
  414.   : PNamedControl(parent, ctlID, notify, valuePtr)
  415. {
  416.   DWORD style = _styleBits&15;
  417.   PAssert(style == BS_DEFPUSHBUTTON || style == BS_PUSHBUTTON,
  418.                                                      ControlResourceMismatch);
  419.   defaultButton = style == BS_DEFPUSHBUTTON;
  420.   foregroundColour.FromSYSCOLOR(COLOR_BTNTEXT);
  421.   backgroundColour.FromSYSCOLOR(COLOR_BTNFACE);
  422. }
  423. void PPushButton::GetCreateWinInfo(WNDCLASS & wndClass)
  424. {
  425.   PNamedControl::GetCreateWinInfo(wndClass);
  426.   if (defaultButton)
  427.     _styleBits |= BS_DEFPUSHBUTTON;
  428.   else
  429.     _styleBits |= BS_PUSHBUTTON;
  430.   if (!IsClass(PTextButton::Class()))
  431.     _styleBits |= BS_OWNERDRAW;
  432.   foregroundColour.FromSYSCOLOR(COLOR_BTNTEXT);
  433.   backgroundColour.FromSYSCOLOR(COLOR_BTNFACE);
  434. }
  435. int PPushButton::TranslateOption(NMHDR & msg) const
  436. {
  437.   return msg.code == BN_CLICKED ? NotifyChange : -1;
  438. }
  439. //////////////////////////////////////////////////////////////////////////////
  440. // PTextButton
  441. void PTextButton::DefaultDimensions()
  442. {
  443.   PDrawCanvas canvas(this);
  444.   PString name = GetName();
  445.   PDim dim(16, 8);
  446.   if (!name.IsEmpty()) {
  447.     dim = canvas.MeasureString(name);
  448.     // 2 average character width either side of the button text and half a
  449.     // character height above and below
  450.     dim += PDim(16, dim.Height());
  451.     if (dim.Width() < dim.Height()*3)
  452.       dim.SetWidth(dim.Height()*3);
  453.   }
  454.   SetDimensions(dim, LocalCoords);
  455. }
  456. //////////////////////////////////////////////////////////////////////////////
  457. // PImageButton
  458. void PImageButton::Construct()
  459. {
  460.   _in_WM_PAINT = TRUE; // Prevent calling OnRedraw in the normal WM_PAINT
  461. }
  462. //////////////////////////////////////////////////////////////////////////////
  463. // PCheck3WayBox
  464. PCheck3WayBox::PCheck3WayBox(PInteractorLayout * parent,
  465.           PRESOURCE_ID ctlID, const PNotifier & notify, CheckValues * valuePtr)
  466.   : PNamedControl(parent, ctlID, notify, valuePtr)
  467. {
  468.   DWORD style = _styleBits&15;
  469.   PAssert(style == BS_AUTO3STATE || style == BS_AUTOCHECKBOX,
  470.                                                      ControlResourceMismatch);
  471.   Construct();
  472. }
  473. void PCheck3WayBox::Construct()
  474. {
  475.   foregroundColour = parent->GetForegroundColour();
  476.   backgroundColour = parent->GetBackgroundColour();
  477. }
  478. void PCheck3WayBox::GetCreateWinInfo(WNDCLASS & wndClass)
  479. {
  480.   PNamedControl::GetCreateWinInfo(wndClass);
  481.   _styleBits |= BS_AUTO3STATE;
  482. }
  483. int PCheck3WayBox::TranslateOption(NMHDR & msg) const
  484. {
  485.   return msg.code == BN_CLICKED ? NotifyChange : -1;
  486. }
  487. //////////////////////////////////////////////////////////////////////////////
  488. // PCheckBox
  489. PCheckBox::PCheckBox(PInteractorLayout * parent,
  490.                  PRESOURCE_ID ctlID, const PNotifier & notify, BOOL * valuePtr)
  491.   : PCheck3WayBox(parent, ctlID, notify, (CheckValues *)valuePtr)
  492. {
  493.   PAssert((_styleBits&15) == BS_AUTOCHECKBOX, ControlResourceMismatch);
  494. }
  495. void PCheckBox::GetCreateWinInfo(WNDCLASS & wndClass)
  496. {
  497.   PCheck3WayBox::GetCreateWinInfo(wndClass);
  498.   _styleBits &= 0xfffffff0;
  499.   _styleBits |= BS_AUTOCHECKBOX;
  500. }
  501. //////////////////////////////////////////////////////////////////////////////
  502. // PRadioButton
  503. PRadioButton::PRadioButton(PInteractorLayout * parent,
  504.                PRESOURCE_ID ctlID, const PNotifier & notify, PINDEX * valuePtr)
  505.   : PNamedControl(parent, ctlID, notify, valuePtr)
  506. {
  507.   PAssert((_styleBits&15) == BS_RADIOBUTTON, ControlResourceMismatch);
  508.   group.DisallowDeleteObjects();
  509.   group.Append(this);
  510.   Construct();
  511. }
  512. void PRadioButton::Construct()
  513. {
  514.   foregroundColour = parent->GetForegroundColour();
  515.   backgroundColour = parent->GetBackgroundColour();
  516. }
  517. PINDEX PRadioButton::GetValue() const
  518. {
  519.   for (PINDEX i = 0; i < group.GetSize(); i++) {
  520.     if (SendMessage(group[i].GetHWND(), BM_GETCHECK, 0, 0L) != 0)
  521.       return i+1;
  522.   }
  523.   return 0;
  524. }
  525. void PRadioButton::SetValue(PINDEX newVal)
  526. {
  527.   for (PINDEX i = 0; i < group.GetSize(); i++)
  528.     SendMessage(group[i].GetHWND(), BM_SETCHECK, newVal == i+1, 0L);
  529. }
  530. void PRadioButton::GetCreateWinInfo(WNDCLASS & wndClass)
  531. {
  532.   PNamedControl::GetCreateWinInfo(wndClass);
  533.   _styleBits |= BS_RADIOBUTTON;
  534. }
  535. int PRadioButton::TranslateOption(NMHDR & msg) const
  536. {
  537.   if (msg.code != BN_CLICKED)
  538.     return -1;
  539.   for (PINDEX i = 0; i < group.GetSize(); i++) {
  540.     PRadioButton & btn = group[i];
  541.     SendMessage(btn.GetHWND(), BM_SETCHECK, &btn == this, 0L);
  542.   }
  543.   return NotifyChange;
  544. }
  545. //////////////////////////////////////////////////////////////////////////////
  546. // PStaticIcon
  547. PStaticIcon::PStaticIcon(PInteractorLayout * parent,
  548.                 PRESOURCE_ID ctlID, const PNotifier & notify, void * valuePtr)
  549.   : PControl(parent, ctlID, notify, valuePtr),
  550. #if defined(_WIN32)
  551.     icon((HICON)NULL)
  552. #else
  553.     icon((HICON)GetWindowWord(_hWnd, 4))
  554. #endif
  555. {
  556.   PAssert((_styleBits&15) == SS_ICON, ControlResourceMismatch);
  557.   foregroundColour = parent->GetForegroundColour();
  558.   backgroundColour = parent->GetBackgroundColour();
  559. }
  560. void PStaticIcon::SetIcon(const PIcon & icn)
  561. {
  562.   HICON oldIcon = (HICON)
  563. #if defined(_WIN32)
  564.                 SendMessage(GetHWND(), STM_SETICON, (WPARAM)icn.GetHICON(), 0);
  565. #else
  566.                 SetWindowWord(GetHWND(), 4, (WORD)icn.GetHICON());
  567. #endif
  568.   if (oldIcon!=NULL && oldIcon!=icon.GetHICON() && oldIcon!=icn.GetHICON())
  569.     DestroyIcon(oldIcon);
  570.   icon = icn;
  571. }
  572. void PStaticIcon::GetCreateWinInfo(WNDCLASS & wndClass)
  573. {
  574.   PControl::GetCreateWinInfo(wndClass);
  575.   wndClass.lpszClassName = "Static";
  576.   _styleBits |= SS_ICON;
  577. }
  578. #if defined(_WIN32)
  579. void PStaticIcon::WndProc()
  580. {
  581.   PControl::WndProc();
  582.   if (_msg->event == WM_CREATE && icon.GetHICON() == NULL)
  583.     icon = PIcon((HICON)SendMessage(_hWnd, STM_GETICON, 0, 0));
  584. }
  585. #endif
  586. //////////////////////////////////////////////////////////////////////////////
  587. // PStaticBox
  588. PStaticBox::PStaticBox(PInteractorLayout * parent,
  589.                 PRESOURCE_ID ctlID, const PNotifier & notify, void * valuePtr)
  590.   : PNamedControl(parent, ctlID, notify, valuePtr)
  591. {
  592.   PAssert((_styleBits&15) == BS_GROUPBOX, ControlResourceMismatch);
  593.   foregroundColour = parent->GetForegroundColour();
  594.   backgroundColour = parent->GetBackgroundColour();
  595. }
  596. void PStaticBox::GetCreateWinInfo(WNDCLASS & wndClass)
  597. {
  598.   PNamedControl::GetCreateWinInfo(wndClass);
  599.   _styleBits |= BS_GROUPBOX;
  600. }
  601. //////////////////////////////////////////////////////////////////////////////
  602. // PStaticRect
  603. void PStaticRect::GetCreateWinInfo(WNDCLASS & wndClass)
  604. {
  605.   PControl::GetCreateWinInfo(wndClass);
  606.   wndClass.lpszClassName = "Static";
  607.   _styleBits |= SS_LEFT;
  608. }
  609. //////////////////////////////////////////////////////////////////////////////
  610. // PChoiceBox
  611. PChoiceBox::PChoiceBox(PInteractorLayout * parent,
  612.                PRESOURCE_ID ctlID, const PNotifier & notify, PINDEX * valuePtr)
  613.   : PControl(parent, ctlID, notify, valuePtr)
  614. {
  615.   sort  = (_styleBits&CBS_SORT) != 0;
  616.   PAssert((_styleBits&CBS_DROPDOWNLIST) != 0, ControlResourceMismatch);
  617. }
  618. void PChoiceBox::GetCreateWinInfo(WNDCLASS & wndClass)
  619. {
  620.   PControl::GetCreateWinInfo(wndClass);
  621.   wndClass.lpszClassName = "ComboBox";
  622.   if (sort)
  623.     _styleBits |= CBS_SORT;
  624.   _styleBits |= WS_BORDER|CBS_DROPDOWNLIST|WS_VSCROLL;
  625. }
  626. int PChoiceBox::TranslateOption(NMHDR & msg) const
  627. {
  628.   switch (msg.code) {
  629.     case CBN_SELCHANGE :
  630.       return NewSelection;
  631.     case CBN_DROPDOWN :
  632.       return ListDropped;
  633.     case CBN_CLOSEUP :
  634.       return ListClosed;
  635.   }
  636.   return -1;
  637. }
  638. //////////////////////////////////////////////////////////////////////////////
  639. // PListBox
  640. PListBox::PListBox(PInteractorLayout * parent,
  641.                PRESOURCE_ID ctlID, const PNotifier & notify, PINDEX * valuePtr)
  642.   : PControl(parent, ctlID, notify, valuePtr)
  643. {
  644.   sort  = (_styleBits&LBS_SORT) != 0;
  645.   multi = (_styleBits&LBS_EXTENDEDSEL) != 0;
  646.   width = (PDIMENSION)((_styleBits&LBS_MULTICOLUMN) != 0 ? 20 : 0);
  647.   PAssert((_styleBits&LBS_NOTIFY) != 0, ControlResourceMismatch);
  648. }
  649. void PListBox::Construct()
  650. {
  651.   if (width != 0 && _hWnd != NULL)
  652.     SetColumnWidth(width, FALSE);
  653. }
  654. void PListBox::DeleteEntry(PINDEX index, BOOL update)
  655. {
  656.   SendMessage(GetHWND(), WM_SETREDRAW, update, 0L);
  657.   BOOL doNotify = GetSelection() == index;
  658.   SendMessage(_hWnd, LB_DELETESTRING, index, 0L);
  659.   if (!update)
  660.     SendMessage(_hWnd, WM_SETREDRAW, TRUE, 0L);
  661.   if (doNotify)
  662.     parent->OnControlNotify(*this, NewSelection);
  663. }
  664. void PListBox::DeleteAllEntries(BOOL update)
  665. {
  666.   SendMessage(GetHWND(), WM_SETREDRAW, update, 0L);
  667.   BOOL doNotify = GetSelection() != P_MAX_INDEX;
  668.   SendMessage(_hWnd, LB_RESETCONTENT, 0, 0L);
  669.   if (!update)
  670.     SendMessage(_hWnd, WM_SETREDRAW, TRUE, 0L);
  671.   if (doNotify)
  672.     parent->OnControlNotify(*this, NewSelection);
  673. }
  674. void PListBox::SetColumnWidth(PDIMENSION newWidth, BOOL update)
  675. {
  676.   PAssert(width != 0 && newWidth != 0, PInvalidParameter);
  677.   width = newWidth;
  678.   SendMessage(GetHWND(), WM_SETREDRAW, update, 0L);
  679.   SendMessage(_hWnd, LB_SETCOLUMNWIDTH, newWidth, 0L);
  680.   if (!update)
  681.     SendMessage(_hWnd, WM_SETREDRAW, TRUE, 0L);
  682. }
  683. void PListBox::SetTopIndex(PINDEX index, BOOL update)
  684. {
  685.   SendMessage(GetHWND(), WM_SETREDRAW, update, 0L);
  686.   SendMessage(_hWnd, LB_SETTOPINDEX, index, 0L);
  687.   if (!update)
  688.     SendMessage(_hWnd, WM_SETREDRAW, TRUE, 0L);
  689. }
  690. PINDEX PListBox::GetSelection() const
  691. {
  692.   long retVal = SendMessage(GetHWND(), LB_GETCURSEL, 0, 0L);
  693.   return retVal != LB_ERR ? (PINDEX)retVal : P_MAX_INDEX;
  694. }
  695. void PListBox::SetSelection(PINDEX index)
  696. {
  697.   if (GetSelection() != index) {
  698.     SendMessage(GetHWND(), LB_SETCURSEL, index, 0L);
  699.     parent->OnControlNotify(*this, NewSelection);
  700.   }
  701. }
  702. void PListBox::Select(PINDEX index, BOOL update, BOOL sel)
  703. {
  704.   SendMessage(GetHWND(), WM_SETREDRAW, update, 0L);
  705.   SendMessage(_hWnd, LB_SETSEL, sel, MAKELPARAM(index, 0));
  706.   if (!update)
  707.     SendMessage(_hWnd, WM_SETREDRAW, TRUE, 0L);
  708.   parent->OnControlNotify(*this, NewSelection);
  709. }
  710. void PListBox::GetCreateWinInfo(WNDCLASS & wndClass)
  711. {
  712.   PControl::GetCreateWinInfo(wndClass);
  713.   wndClass.lpszClassName = "ListBox";
  714.   if (sort)
  715.     _styleBits |= LBS_SORT;
  716.   if (multi)
  717.     _styleBits |= LBS_EXTENDEDSEL;
  718.   if (width != 0)
  719.     _styleBits |= LBS_MULTICOLUMN|WS_HSCROLL;
  720.   else
  721.     _styleBits |= WS_VSCROLL;
  722.   _styleBits |= WS_BORDER|LBS_NOINTEGRALHEIGHT|LBS_NOTIFY|LBS_DISABLENOSCROLL;
  723. }
  724. int PListBox::TranslateOption(NMHDR & msg) const
  725. {
  726.   switch (msg.code) {
  727.     case LBN_SELCHANGE :
  728.       return NewSelection;
  729.     case LBN_DBLCLK :
  730.       return DoubleClick;
  731.   }
  732.   return -1;
  733. }
  734. void PListBox::CreateHWND()
  735. {
  736.   PControl::CreateHWND();
  737.   if (width != 0)
  738.     SetColumnWidth(width, FALSE);
  739. }
  740. void PListBox::WndProc()
  741. {
  742.   if (_msg->event == WM_DESTROY && deleteObjects && IsDescendant(PCustomListBox::Class())) {
  743.     for (PINDEX i = 0; i < GetCount(); i++) {
  744.       LPARAM itemData = SendMessage(GetHWND(), LB_GETITEMDATA, i, 0L);
  745.       if (itemData != LB_ERR)
  746.         delete (PObject *)itemData;
  747.     }
  748.   }
  749.   PControl::WndProc();
  750. }
  751. BOOL PListBox::AdjustDimensionForScrollBar(UINT) const
  752. {
  753.   return FALSE;
  754. }
  755. //////////////////////////////////////////////////////////////////////////////
  756. // PStringListBox
  757. PINDEX PStringListBox::AddString(const PString & str, BOOL update)
  758. {
  759.   SendMessage(GetHWND(), WM_SETREDRAW, update, 0L);
  760.   PINDEX retval = (PINDEX)SendMessage(_hWnd, LB_ADDSTRING, 0, (DWORD)(const char *)str);
  761.   if (!update)
  762.     SendMessage(_hWnd, WM_SETREDRAW, TRUE, 0L);
  763.   return retval;
  764. }
  765. void PStringListBox::InsertString(const PString & str, PINDEX index, BOOL update)
  766. {
  767.   SendMessage(GetHWND(), WM_SETREDRAW, update, 0L);
  768.   SendMessage(_hWnd, LB_INSERTSTRING, index, (DWORD)(const char *)str);
  769.   if (!update)
  770.     SendMessage(_hWnd, WM_SETREDRAW, TRUE, 0L);
  771. }
  772. void PStringListBox::DeleteString(PINDEX index, BOOL update)
  773. {
  774.   DeleteEntry(index, update);
  775. }
  776. PINDEX PStringListBox::FindString(const PString & str, PINDEX startIndex, BOOL exact) const
  777. {
  778.   if (startIndex == P_MAX_INDEX)
  779.     startIndex = -1;
  780.   long retVal = SendMessage(GetHWND(),
  781.                       exact ? LB_FINDSTRINGEXACT : LB_FINDSTRING, startIndex,
  782.                       (DWORD)(const char *)str);
  783.   return retVal != LB_ERR ? (PINDEX)retVal : P_MAX_INDEX;
  784. }
  785. PString PStringListBox::GetString(PINDEX index) const
  786. {
  787.   PString str;
  788.   long len = SendMessage(GetHWND(), LB_GETTEXTLEN, index, 0);
  789.   if (len != LB_ERR)
  790.     SendMessage(GetHWND(), LB_GETTEXT, index, (DWORD)str.GetPointer(len+1));
  791.   return str;
  792. }
  793. void PStringListBox::SetTabStops(PDIMENSION tab)
  794. {
  795.   tabStops.SetSize(1);
  796.   tabStops[0] = tab;
  797.   SendMessage(GetHWND(), LB_SETTABSTOPS, 1, (LPARAM)&tab);
  798. }
  799. void PStringListBox::SetTabStops(const PORDINATE * tabs, PINDEX count)
  800. {
  801.   PAssert(count > 0, PInvalidParameter);
  802.   memcpy(tabStops.GetPointer(count), tabs, count*sizeof(int));
  803.   SendMessage(GetHWND(), LB_SETTABSTOPS, count, (LPARAM)tabs);
  804. }
  805. void PStringListBox::SetTabStops(const PIntArray & tabs)
  806. {
  807.   PAssert(tabs.GetSize() > 0, PInvalidParameter);
  808.   SendMessage(GetHWND(), LB_SETTABSTOPS,
  809.               tabs.GetSize(), (LPARAM)(const int *)tabs);
  810. }
  811. void PStringListBox::GetCreateWinInfo(WNDCLASS & wndClass)
  812. {
  813.   PListBox::GetCreateWinInfo(wndClass);
  814.   _styleBits |= LBS_USETABSTOPS;
  815. }
  816. //////////////////////////////////////////////////////////////////////////////
  817. // PCustomListBox
  818. PINDEX PCustomListBox::AddEntry(PObject * obj, BOOL update)
  819. {
  820.   SendMessage(GetHWND(), WM_SETREDRAW, update, 0L);
  821.   PINDEX retval = (PINDEX)SendMessage(_hWnd, LB_ADDSTRING, 0, (DWORD)obj);
  822.   if (!update)
  823.     SendMessage(_hWnd, WM_SETREDRAW, TRUE, 0L);
  824.   return retval;
  825. }
  826. void PCustomListBox::InsertEntry(PObject * obj, PINDEX index, BOOL update)
  827. {
  828.   SendMessage(GetHWND(), WM_SETREDRAW, update, 0L);
  829.   SendMessage(_hWnd, LB_INSERTSTRING, index, (DWORD)obj);
  830.   if (!update)
  831.     SendMessage(_hWnd, WM_SETREDRAW, TRUE, 0L);
  832. }
  833. PINDEX PCustomListBox::FindEntry(const PObject & obj, PINDEX startIndex) const
  834. {
  835.   if (startIndex == P_MAX_INDEX)
  836.     startIndex = -1;
  837.   long retVal = SendMessage(_hWnd,
  838.           LB_FINDSTRINGEXACT, startIndex, (DWORD)(const char *)(PString &)obj);
  839.   return retVal != LB_ERR ? (PINDEX)retVal : P_MAX_INDEX;
  840. }
  841. void PCustomListBox::SetEntry(PObject * obj, PINDEX index, BOOL update)
  842. {
  843.   SendMessage(GetHWND(), WM_SETREDRAW, update, 0L);
  844.   BOOL doNotify = GetSelection() == index;
  845.   SendMessage(_hWnd, LB_SETITEMDATA, index, (DWORD)obj);
  846.   if (!update)
  847.     SendMessage(_hWnd, WM_SETREDRAW, TRUE, 0L);
  848.   if (doNotify)
  849.     parent->OnControlNotify(*this, NewSelection);
  850. }
  851. const PObject * PCustomListBox::GetEntry(PINDEX index) const
  852. {
  853.   long retVal = SendMessage(GetHWND(), LB_GETITEMDATA, index, 0L);
  854.   return retVal != LB_ERR ? (const PObject *)retVal : NULL;
  855. }
  856. void PCustomListBox::GetCreateWinInfo(WNDCLASS & wndClass)
  857. {
  858.   PListBox::GetCreateWinInfo(wndClass);
  859.   _styleBits |= LBS_OWNERDRAWVARIABLE;
  860. }
  861. //////////////////////////////////////////////////////////////////////////////
  862. // PComboBox
  863. PComboBox::PComboBox(PInteractorLayout * parent,
  864.               PRESOURCE_ID ctlID, const PNotifier & notify, PString * valuePtr)
  865.   : PControl(parent, ctlID, notify, valuePtr)
  866. {
  867.   sort  = (_styleBits&CBS_SORT) != 0;
  868.   PAssert((_styleBits&CBS_DROPDOWN) != 0, ControlResourceMismatch);
  869. }
  870. PINDEX PComboBox::GetCurrent() const
  871. {
  872.   long retVal = SendMessage(GetHWND(), CB_GETCURSEL, 0, 0L);
  873.   return retVal != CB_ERR ? (PINDEX)retVal : P_MAX_INDEX;
  874. }
  875. void PComboBox::GetCreateWinInfo(WNDCLASS & wndClass)
  876. {
  877.   PControl::GetCreateWinInfo(wndClass);
  878.   wndClass.lpszClassName = "ComboBox";
  879.   if (sort != 0)
  880.     _styleBits |= CBS_SORT;
  881.   _styleBits |= CBS_DROPDOWN|CBS_AUTOHSCROLL|WS_VSCROLL;
  882. }
  883. int PComboBox::TranslateOption(NMHDR & msg) const
  884. {
  885.   switch (msg.code) {
  886.     case CBN_SELCHANGE :
  887.       return NewSelection;
  888.     case CBN_DROPDOWN :
  889.       return ListDropped;
  890.     case CBN_CLOSEUP :
  891.       return ListClosed;
  892.     case CBN_EDITCHANGE :
  893.      return EditChange;
  894.   }
  895.   return -1;
  896. }
  897. BOOL PComboBox::OnEndInput()
  898. {
  899.   parent->OnControlNotify(*this, PEditBox::EndEdit);
  900.   return TRUE;
  901. }
  902. //////////////////////////////////////////////////////////////////////////////
  903. // PScrollBar
  904. PScrollBar::PScrollBar(PInteractorLayout * parent, PRESOURCE_ID ctlID,
  905.                          const PNotifier & notify, PSCROLLBAR_VALUE * valuePtr)
  906.   : PControl(parent, ctlID, notify, valuePtr)
  907. {
  908.   PStringArray limits = GetWndText().Tokenise(" ");
  909.   value = minimum = 0;
  910.   maximum = 100;
  911.   smallNudge = 1;
  912.   largeNudge = 10;
  913.   switch (limits.GetSize()) {
  914.     case 4 :
  915.       largeNudge = (PSCROLLBAR_VALUE)limits[3].AsInteger();
  916.     case 3 :
  917.       smallNudge = (PSCROLLBAR_VALUE)limits[2].AsInteger();
  918.     case 2 :
  919.       maximum = (PSCROLLBAR_VALUE)limits[1].AsInteger();
  920.     case 1 :
  921.       value = minimum = (PSCROLLBAR_VALUE)limits[0].AsInteger();
  922.   }
  923.   SetScrollRange(_hWnd, SB_CTL, minimum, maximum, FALSE);
  924.   SetScrollPos(_hWnd, SB_CTL, value, FALSE);
  925.   tracking = FALSE;
  926.   foregroundColour = owner->GetScrollBarColour();
  927.   backgroundColour = owner->GetScrollBarColour();
  928. }
  929. void PScrollBar::SetMaximum(PSCROLLBAR_VALUE val, BOOL redraw)
  930. {
  931.   maximum = val;
  932.   if (minimum > maximum)
  933.     minimum = maximum;
  934.   SetScrollRange(GetHWND(), SB_CTL, minimum, maximum, redraw);
  935.   SetValue(value);
  936. }
  937. void PScrollBar::SetMinimum(PSCROLLBAR_VALUE val, BOOL redraw)
  938. {
  939.   minimum = val;
  940.   if (maximum < minimum)
  941.     maximum = minimum;
  942.   SetScrollRange(GetHWND(), SB_CTL, minimum, maximum, redraw);
  943.   SetValue(value);
  944. }
  945. void PScrollBar::SetValue(PSCROLLBAR_VALUE val, BOOL redraw)
  946. {
  947.   SetScrollPos(GetHWND(), SB_CTL, val, redraw);
  948.   PSCROLLBAR_VALUE newValue = (PSCROLLBAR_VALUE)GetScrollPos(_hWnd, SB_CTL);
  949.   if (value != newValue) {
  950.     parent->OnControlNotify(*this, StartTrack);
  951.     value = newValue;
  952.     parent->OnControlNotify(*this, EndTrack);
  953.   }
  954. }
  955. int PScrollBar::TrackScrollBar(WPARAM code, int trackVal)
  956. {
  957.   int newVal = value;
  958.   switch (code) {
  959.     case SB_LINEUP :
  960.       newVal -= smallNudge;
  961.       break;
  962.     case SB_LINEDOWN :
  963.       newVal += smallNudge;
  964.       break;
  965.     case SB_PAGEUP :
  966.       newVal -= largeNudge;
  967.       break;
  968.     case SB_PAGEDOWN :
  969.       newVal += largeNudge;
  970.       break;
  971.     case SB_TOP :
  972.       newVal = minimum;
  973.       break;
  974.     case SB_BOTTOM :
  975.       newVal = maximum;
  976.       break;
  977.     case SB_THUMBTRACK :
  978.     case SB_THUMBPOSITION :
  979.       newVal = trackVal;
  980.   }
  981.   SetScrollPos(_hWnd, SB_CTL, newVal, TRUE);
  982.   value = (PSCROLLBAR_VALUE)GetScrollPos(_hWnd, SB_CTL);
  983.   if (tracking) {
  984.     if (code != SB_ENDSCROLL)
  985.       return Tracking;
  986.     tracking = FALSE;
  987.     return EndTrack;
  988.   }
  989.   tracking = TRUE;
  990.   return StartTrack;
  991. }
  992. void PScrollBar::CreateHWND()
  993. {
  994.   PControl::CreateHWND();
  995.   SetScrollRange(_hWnd, SB_CTL, minimum, maximum, FALSE);
  996.   SetScrollPos(_hWnd, SB_CTL, value, TRUE);
  997.   foregroundColour = owner->GetScrollBarColour();
  998.   backgroundColour = owner->GetScrollBarColour();
  999. }
  1000. void PScrollBar::GetCreateWinInfo(WNDCLASS & wndClass)
  1001. {
  1002.   PControl::GetCreateWinInfo(wndClass);
  1003.   wndClass.lpszClassName = "ScrollBar";
  1004.   _styleBits |= WS_TABSTOP;
  1005. }
  1006. PVerticalScrollBar::PVerticalScrollBar(PInteractorLayout * parent,
  1007.      PRESOURCE_ID ctlID, const PNotifier & notify, PSCROLLBAR_VALUE * valuePtr)
  1008.   : PScrollBar(parent, ctlID, notify, valuePtr)
  1009. {
  1010.   PAssert((_styleBits&1)!=0, ControlResourceMismatch);
  1011. }
  1012. void PVerticalScrollBar::GetCreateWinInfo(WNDCLASS & wndClass)
  1013. {
  1014.   PScrollBar::GetCreateWinInfo(wndClass);
  1015.   _styleBits |= SBS_VERT;
  1016. }
  1017. PHorizontalScrollBar::PHorizontalScrollBar(PInteractorLayout * parent,
  1018.      PRESOURCE_ID ctlID, const PNotifier & notify, PSCROLLBAR_VALUE * valuePtr)
  1019.   : PScrollBar(parent, ctlID, notify, valuePtr)
  1020. {
  1021.   PAssert((_styleBits&1)==0,ControlResourceMismatch);
  1022. }
  1023. void PHorizontalScrollBar::GetCreateWinInfo(WNDCLASS & wndClass)
  1024. {
  1025.   PScrollBar::GetCreateWinInfo(wndClass);
  1026.   _styleBits |= SBS_HORZ;
  1027. }
  1028. // End Of File ///////////////////////////////////////////////////////////////