home *** CD-ROM | disk | FTP | other *** search
/ PC Plus SuperCD (UK) 2000 May / PCP163A.iso / Runimage / Cbuilder4 / Source / Vcl / MULTIMON.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-01-26  |  14.8 KB  |  451 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Borland Delphi Run-time Library                 }
  5. {       Win32 multi-monitor support interface unit      }
  6. {                                                       }
  7. {       Copyright (c) 1998 Inprise Corporation          }
  8. {                                                       }
  9. {*******************************************************}
  10.  
  11. unit MultiMon;
  12.  
  13. (*
  14.  * MultiMon unit provides access to the new MultiMonitor
  15.  * APIs provided in Win98 and NT5 and greater.  For
  16.  * backwards compatibility, the new APIs are stubbed out
  17.  * here for older Win32 OS systems.
  18.  *)
  19.  
  20. interface
  21.  
  22. uses Windows;
  23.  
  24. {$HPPEMIT '#include <multimon.h>' }
  25.  
  26. const
  27.   { GetSystemMetrics() codes }
  28.   SM_XVIRTUALSCREEN = 76;
  29.   {$EXTERNALSYM SM_XVIRTUALSCREEN}
  30.   SM_YVIRTUALSCREEN = 77;
  31.   {$EXTERNALSYM SM_YVIRTUALSCREEN}
  32.   SM_CXVIRTUALSCREEN = 78;
  33.   {$EXTERNALSYM SM_CXVIRTUALSCREEN}
  34.   SM_CYVIRTUALSCREEN = 79;
  35.   {$EXTERNALSYM SM_CYVIRTUALSCREEN}
  36.   SM_CMONITORS = 80;
  37.   {$EXTERNALSYM SM_CMONITORS}
  38.   SM_SAMEDISPLAYFORMAT = 81;
  39.   {$EXTERNALSYM SM_SAMEDISPLAYFORMAT}
  40.   SM_CMETRICS = 83;
  41.   {$EXTERNALSYM SM_CMETRICS}
  42.  
  43. type
  44.   HMONITOR = type Integer;
  45.   {$EXTERNALSYM HMONITOR}
  46.  
  47. const
  48.   MONITOR_DEFAULTTONULL = $0;
  49.   {$EXTERNALSYM MONITOR_DEFAULTTONULL}
  50.   MONITOR_DEFAULTTOPRIMARY = $1;
  51.   {$EXTERNALSYM MONITOR_DEFAULTTOPRIMARY}
  52.   MONITOR_DEFAULTTONEAREST = $2;
  53.   {$EXTERNALSYM MONITOR_DEFAULTTONEAREST}
  54.   MONITORINFOF_PRIMARY = $1;
  55.   {$EXTERNALSYM MONITORINFOF_PRIMARY}
  56.  
  57. const
  58.   CCHDEVICENAME = 32;
  59.   {$EXTERNALSYM CCHDEVICENAME}
  60.  
  61. type
  62.   {$EXTERNALSYM tagMONITORINFOA}
  63.   tagMONITORINFOA = record
  64.     cbSize: DWORD;
  65.     rcMonitor: TRect;
  66.     rcWork: TRect;
  67.     dwFlags: DWORD;
  68.   end;
  69.   {$EXTERNALSYM tagMONITORINFOW}
  70.   tagMONITORINFOW = record
  71.     cbSize: DWORD;
  72.     rcMonitor: TRect;
  73.     rcWork: TRect;
  74.     dwFlags: DWORD;
  75.   end;
  76.   {$EXTERNALSYM tagMONITORINFO}
  77.   tagMONITORINFO = tagMONITORINFOA;
  78.   {$EXTERNALSYM MONITORINFOA}
  79.   MONITORINFOA = tagMONITORINFOA;
  80.   {$EXTERNALSYM MONITORINFOW}
  81.   MONITORINFOW = tagMONITORINFOW;
  82.   {$EXTERNALSYM MONITORINFO}
  83.   MONITORINFO = MONITORINFOA;
  84.   {$EXTERNALSYM LPMONITORINFOA}
  85.   LPMONITORINFOA = ^tagMONITORINFOA;
  86.   {$EXTERNALSYM LPMONITORINFOW}
  87.   LPMONITORINFOW = ^tagMONITORINFOW;
  88.   {$EXTERNALSYM LPMONITORINFO}
  89.   LPMONITORINFO = LPMONITORINFOA;
  90.   {$EXTERNALSYM PMonitorInfoA}
  91.   PMonitorInfoA = ^tagMONITORINFO;
  92.   {$EXTERNALSYM PMonitorInfoW}
  93.   PMonitorInfoW = ^tagMONITORINFO;
  94.   {$EXTERNALSYM PMonitorInfo}
  95.   PMonitorInfo = PMonitorInfoA;
  96.   {$EXTERNALSYM TMonitorInfoA}
  97.   TMonitorInfoA = tagMONITORINFO;
  98.   {$EXTERNALSYM TMonitorInfoW}
  99.   TMonitorInfoW = tagMONITORINFO;
  100.   {$EXTERNALSYM TMonitorInfo}
  101.   TMonitorInfo = TMonitorInfoA;
  102.  
  103.   {$EXTERNALSYM tagMONITORINFOEXA}
  104.   tagMONITORINFOEXA = record
  105.     cbSize: DWORD;
  106.     rcMonitor: TRect;
  107.     rcWork: TRect;
  108.     dwFlags: DWORD;
  109.     szDevice: array[0..CCHDEVICENAME] of AnsiChar;
  110.   end;
  111.   {$EXTERNALSYM tagMONITORINFOEXW}
  112.   tagMONITORINFOEXW = record
  113.     cbSize: DWORD;
  114.     rcMonitor: TRect;
  115.     rcWork: TRect;
  116.     dwFlags: DWORD;
  117.     szDevice: array[0..CCHDEVICENAME] of WideChar;
  118.   end;
  119.   {$EXTERNALSYM tagMONITORINFOEX}
  120.   tagMONITORINFOEX = tagMONITORINFOEXA;
  121.   {$EXTERNALSYM MONITORINFOEXA}
  122.   MONITORINFOEXA = tagMONITORINFOEXA;
  123.   {$EXTERNALSYM MONITORINFOEXW}
  124.   MONITORINFOEXW = tagMONITORINFOEXW;
  125.   {$EXTERNALSYM MONITORINFOEX}
  126.   MONITORINFOEX = MONITORINFOEXA;
  127.   {$EXTERNALSYM LPMONITORINFOEXA}
  128.   LPMONITORINFOEXA = ^tagMONITORINFOEXA;
  129.   {$EXTERNALSYM LPMONITORINFOEXW}
  130.   LPMONITORINFOEXW = ^tagMONITORINFOEXW;
  131.   {$EXTERNALSYM LPMONITORINFOEX}
  132.   LPMONITORINFOEX = LPMONITORINFOEXA;
  133.   {$EXTERNALSYM PMonitorInfoExA}
  134.   PMonitorInfoExA = ^tagMONITORINFOEX;
  135.   {$EXTERNALSYM PMonitorInfoExW}
  136.   PMonitorInfoExW = ^tagMONITORINFOEX;
  137.   {$EXTERNALSYM PMonitorInfoEx}
  138.   PMonitorInfoEx = PMonitorInfoExA;
  139.   {$EXTERNALSYM TMonitorInfoExA}
  140.   TMonitorInfoExA = tagMONITORINFOEX;
  141.   {$EXTERNALSYM TMonitorInfoExW}
  142.   TMonitorInfoExW = tagMONITORINFOEX;
  143.   {$EXTERNALSYM TMonitorInfoEx}
  144.   TMonitorInfoEx = TMonitorInfoExA;
  145.  
  146. {$EXTERNALSYM TMonitorEnumProc}
  147.   TMonitorEnumProc = function(hm: HMONITOR; dc: HDC; r: PRect; l: LPARAM): Boolean; stdcall;
  148. {$EXTERNALSYM TGetSystemMetrics}
  149.   TGetSystemMetrics = function(nIndex: Integer): Integer; stdcall;
  150. {$EXTERNALSYM TMonitorFromWindow}
  151.   TMonitorFromWindow = function(hWnd: HWND; dwFlags: DWORD): HMONITOR; stdcall;
  152. {$EXTERNALSYM TMonitorFromRect}
  153.   TMonitorFromRect = function(lprcScreenCoords: PRect; dwFlags: DWORD): HMONITOR; stdcall;
  154. {$EXTERNALSYM TMonitorFromPoint}
  155.   TMonitorFromPoint = function(ptScreenCoords: TPoint; dwFlags: DWORD): HMONITOR; stdcall;
  156. {$EXTERNALSYM TGetMonitorInfoA}
  157.   TGetMonitorInfoA = function(hMonitor: HMONITOR; lpMonitorInfo: PMonitorInfoA): Boolean; stdcall;
  158. {$EXTERNALSYM TGetMonitorInfoW}
  159.   TGetMonitorInfoW = function(hMonitor: HMONITOR; lpMonitorInfo: PMonitorInfoW): Boolean; stdcall;
  160.   {$EXTERNALSYM TGetMonitorInfo}
  161.   TGetMonitorInfo = TGetMonitorInfoA;
  162. {$EXTERNALSYM TEnumDisplayMonitors}
  163.   TEnumDisplayMonitors = function(hdc: HDC; lprcIntersect: PRect; lpfnEnumProc: TMonitorEnumProc;
  164.     lData: LPARAM): Boolean; stdcall;
  165.  
  166. var
  167.   {$EXTERNALSYM GetSystemMetrics}
  168.   GetSystemMetrics: TGetSystemMetrics;
  169.   {$EXTERNALSYM MonitorFromWindow}
  170.   MonitorFromWindow: TMonitorFromWindow; 
  171.   {$EXTERNALSYM MonitorFromRect}
  172.   MonitorFromRect: TMonitorFromRect; 
  173.   {$EXTERNALSYM MonitorFromPoint}
  174.   MonitorFromPoint: TMonitorFromPoint;
  175.   {$EXTERNALSYM GetMonitorInfoA}
  176.   {procedure}GetMonitorInfoA: TGetMonitorInfoA;
  177.   {$EXTERNALSYM GetMonitorInfoW}
  178.   {procedure}GetMonitorInfoW: TGetMonitorInfoW;
  179.   {$EXTERNALSYM GetMonitorInfo}
  180.   {procedure}GetMonitorInfo: TGetMonitorInfo;
  181.   {$EXTERNALSYM EnumDisplayMonitors}
  182.   EnumDisplayMonitors: TEnumDisplayMonitors;
  183.  
  184. implementation
  185.  
  186. type
  187.   TMultiMonApi = (mmGetSystemMetrics, mmMonitorFromWindow, mmMonitorFromRect,
  188.     mmMonitorFromPoint, mmGetMonitorInfo, mmGetMonitorInfoA, mmGetMonitorInfoW,
  189.     mmEnumDisplayMonitors);
  190.  
  191. const
  192.   xPRIMARY_MONITOR = HMONITOR($12340042);
  193.   sUser32 = 'USER32.DLL';
  194.  
  195. var
  196.   User32Dll: THandle;
  197.   InitApis: array [mmGetSystemMetrics..mmEnumDisplayMonitors] of Boolean;
  198.   MMAvailable: Boolean;
  199.  
  200. function InitAnApi(mmAPI: TMultiMonApi; ApiStub: Pointer; ApiName: string): Pointer;
  201. begin
  202.   Result := nil;
  203.   if not InitApis[mmApi] then
  204.   begin
  205.     if User32Dll <> 0 then
  206.     begin
  207.       if (mmAPI = mmGetSystemMetrics) and not MMAvailable then
  208.       begin
  209.         @GetMonitorInfo := InitAnApi(mmGetMonitorInfo, @GetMonitorInfo, 'GetMonitorInfoA');
  210.         if not MMAvailable then
  211.           ApiName := '';
  212.       end;
  213.       Result := GetProcAddress(User32Dll, PChar(ApiName))
  214.     end else Result := nil;
  215.     if not Assigned(Result) then
  216.       Result := ApiStub
  217.     else if (mmAPI <> mmGetSystemMetrics) then
  218.       MMAvailable := True;
  219.     InitApis[mmApi] := True;
  220.   end;
  221. end;
  222.  
  223. function _GetSystemMetrics(nIndex: Integer): Integer; stdcall;
  224. begin
  225.   if not InitApis[mmGetSystemMetrics] then
  226.   begin
  227.     @GetSystemMetrics := InitAnApi(mmGetSystemMetrics, @GetSystemMetrics, 'GetSystemMetrics');
  228.     Result := GetSystemMetrics(nIndex);
  229.     Exit;
  230.   end;
  231.  
  232.   Result := -1;
  233.   case nIndex of
  234.     SM_CMONITORS,
  235.     SM_SAMEDISPLAYFORMAT:
  236.       Result := 1;
  237.     SM_XVIRTUALSCREEN,
  238.     SM_YVIRTUALSCREEN:
  239.       Result := 0;
  240.     SM_CXVIRTUALSCREEN:
  241.       nIndex := SM_CXSCREEN;
  242.     SM_CYVIRTUALSCREEN:
  243.       nIndex := SM_CYSCREEN;
  244.   end;
  245.   if Result = -1 then
  246.     Result := Windows.GetSystemMetrics(nIndex);
  247. end;
  248.  
  249. function xMonitorFromRect(lprcScreenCoords: PRect; dwFlags: DWORD): HMONITOR; stdcall;
  250. begin
  251.   if not InitApis[mmMonitorFromRect] then
  252.   begin
  253.     @MonitorFromRect := InitAnApi(mmMonitorFromRect, @MonitorFromRect, 'MonitorFromRect');
  254.     Result := MonitorFromRect(lprcScreenCoords, dwFlags);
  255.     Exit;
  256.   end;
  257.  
  258.   Result := 0;
  259.   if Boolean(dwFlags and (MONITOR_DEFAULTTOPRIMARY or MONITOR_DEFAULTTONEAREST)) and
  260.     (lprcScreenCoords.Right > 0) and
  261.     (lprcScreenCoords.Bottom > 0) and
  262.     (lprcScreenCoords.Left < GetSystemMetrics(SM_CXSCREEN)) and
  263.     (lprcScreenCoords.Top < GetSystemMetrics(SM_CYSCREEN)) then
  264.       Result := xPRIMARY_MONITOR;
  265. end;
  266.  
  267. function xMonitorFromWindow(hWnd: HWND; dwFlags: DWORD): HMONITOR; stdcall;
  268. var
  269.   wp: TWindowPlacement;
  270. begin
  271.   if not InitApis[mmMonitorFromWindow] then
  272.   begin
  273.     @MonitorFromWindow := InitAnApi(mmMonitorFromWindow, @MonitorFromWindow, 'MonitorFromWindow');
  274.     Result := MonitorFromWindow(hWnd, dwFlags);
  275.     Exit;
  276.   end;
  277.  
  278.   if Boolean(dwFlags and (MONITOR_DEFAULTTOPRIMARY or MONITOR_DEFAULTTONEAREST)) then
  279.     Result := xPRIMARY_MONITOR
  280.   else
  281.   begin
  282.     if IsIconic(hWnd) then
  283.       GetWindowPlacement(hWnd, @wp)
  284.     else
  285.       GetWindowRect(hWnd, wp.rcNormalPosition);
  286.     Result := xMonitorFromRect(@wp.rcNormalPosition, dwFlags);
  287.   end
  288. end;
  289.  
  290. function xMonitorFromPoint(ptScreenCoords: TPoint; dwFlags: DWORD): HMONITOR; stdcall;
  291. begin
  292.   if not InitApis[mmMonitorFromPoint] then
  293.   begin
  294.     @MonitorFromPoint := InitAnApi(mmMonitorFromPoint, @MonitorFromPoint, 'MonitorFromPoint');
  295.     Result := MonitorFromPoint(ptScreenCoords, dwFlags);
  296.     Exit;
  297.   end;
  298.  
  299.   Result := 0;
  300.   if Boolean(dwFlags and (MONITOR_DEFAULTTOPRIMARY or MONITOR_DEFAULTTONEAREST)) and
  301.     (ptScreenCoords.X >= 0) and
  302.     (ptScreenCoords.X < GetSystemMetrics(SM_CXSCREEN)) and
  303.     (ptScreenCoords.Y >= 0 ) and
  304.     (ptScreenCoords.Y < GetSystemMetrics(SM_CYSCREEN)) then
  305.       Result := xPRIMARY_MONITOR;
  306. end;
  307.  
  308. function xGetMonitorInfoA(hMonitor: HMONITOR; lpMonitorInfo: PMonitorInfoA): Boolean; stdcall;
  309. var
  310.   rcWork: TRect;
  311. begin
  312.   if not InitApis[mmGetMonitorInfoA] then
  313.   begin
  314.     @GetMonitorInfoA := InitAnApi(mmGetMonitorInfoA, @GetMonitorInfoA, 'GetMonitorInfoA');
  315.     Result := GetMonitorInfoA(hMonitor, lpMonitorInfo);
  316.     Exit;
  317.   end;
  318.  
  319.   Result := False;
  320.   if (hMonitor = xPRIMARY_MONITOR) and (lpMonitorInfo <> nil) and
  321.     (lpMonitorInfo.cbSize >= DWORD(SizeOf(TMonitorInfo))) and
  322.     SystemParametersInfo (SPI_GETWORKAREA, 0, @rcWork, 0) then
  323.     begin
  324.       lpMonitorInfo.rcMonitor.Left := 0;
  325.       lpMonitorInfo.rcMonitor.Top := 0;
  326.       lpMonitorInfo.rcMonitor.Right := GetSystemMetrics(SM_CXSCREEN);
  327.       lpMonitorInfo.rcMonitor.Bottom := GetSystemMetrics(SM_CYSCREEN);
  328.       lpMonitorInfo.rcWork := rcWork;
  329.       lpMonitorInfo.dwFlags := MONITORINFOF_PRIMARY;
  330.       if (lpMonitorInfo.cbSize >= DWORD(SizeOf(TMonitorInfoEx))) then
  331.         lstrcpy(PMonitorInfoEx(lpMonitorInfo).szDevice, 'DISPLAY'); // do not localize
  332.       Result := True;
  333.     end;
  334. end;
  335. function xGetMonitorInfoW(hMonitor: HMONITOR; lpMonitorInfo: PMonitorInfoW): Boolean; stdcall;
  336. var
  337.   rcWork: TRect;
  338. begin
  339.   if not InitApis[mmGetMonitorInfoW] then
  340.   begin
  341.     @GetMonitorInfoW := InitAnApi(mmGetMonitorInfoW, @GetMonitorInfoW, 'GetMonitorInfoW');
  342.     Result := GetMonitorInfoW(hMonitor, lpMonitorInfo);
  343.     Exit;
  344.   end;
  345.  
  346.   Result := False;
  347.   if (hMonitor = xPRIMARY_MONITOR) and (lpMonitorInfo <> nil) and
  348.     (lpMonitorInfo.cbSize >= DWORD(SizeOf(TMonitorInfo))) and
  349.     SystemParametersInfo (SPI_GETWORKAREA, 0, @rcWork, 0) then
  350.     begin
  351.       lpMonitorInfo.rcMonitor.Left := 0;
  352.       lpMonitorInfo.rcMonitor.Top := 0;
  353.       lpMonitorInfo.rcMonitor.Right := GetSystemMetrics(SM_CXSCREEN);
  354.       lpMonitorInfo.rcMonitor.Bottom := GetSystemMetrics(SM_CYSCREEN);
  355.       lpMonitorInfo.rcWork := rcWork;
  356.       lpMonitorInfo.dwFlags := MONITORINFOF_PRIMARY;
  357.       if (lpMonitorInfo.cbSize >= DWORD(SizeOf(TMonitorInfoEx))) then
  358.         lstrcpy(PMonitorInfoEx(lpMonitorInfo).szDevice, 'DISPLAY'); // do not localize
  359.       Result := True;
  360.     end;
  361. end;
  362. function xGetMonitorInfo(hMonitor: HMONITOR; lpMonitorInfo: PMonitorInfo): Boolean; stdcall;
  363. var
  364.   rcWork: TRect;
  365. begin
  366.   if not InitApis[mmGetMonitorInfo] then
  367.   begin
  368.     @GetMonitorInfo := InitAnApi(mmGetMonitorInfo, @GetMonitorInfo, 'GetMonitorInfo');
  369.     Result := GetMonitorInfo(hMonitor, lpMonitorInfo);
  370.     Exit;
  371.   end;
  372.  
  373.   Result := False;
  374.   if (hMonitor = xPRIMARY_MONITOR) and (lpMonitorInfo <> nil) and
  375.     (lpMonitorInfo.cbSize >= DWORD(SizeOf(TMonitorInfo))) and
  376.     SystemParametersInfo (SPI_GETWORKAREA, 0, @rcWork, 0) then
  377.     begin
  378.       lpMonitorInfo.rcMonitor.Left := 0;
  379.       lpMonitorInfo.rcMonitor.Top := 0;
  380.       lpMonitorInfo.rcMonitor.Right := GetSystemMetrics(SM_CXSCREEN);
  381.       lpMonitorInfo.rcMonitor.Bottom := GetSystemMetrics(SM_CYSCREEN);
  382.       lpMonitorInfo.rcWork := rcWork;
  383.       lpMonitorInfo.dwFlags := MONITORINFOF_PRIMARY;
  384.       if (lpMonitorInfo.cbSize >= DWORD(SizeOf(TMonitorInfoEx))) then
  385.         lstrcpy(PMonitorInfoEx(lpMonitorInfo).szDevice, 'DISPLAY'); // do not localize
  386.       Result := True;
  387.     end;
  388. end;
  389.  
  390. function xEnumDisplayMonitors(hdcOptionalForPainting: HDC; lprcEnumMonitorsThatIntersect: PRect;
  391.     lpfnEnumProc: TMonitorEnumProc; dwData: LPARAM): Boolean; stdcall;
  392. var
  393.   rcLimit, rcClip: TRect;
  394.   ptOrg: TPoint;
  395.   ClipBox: Integer;
  396. begin
  397.   if not InitApis[mmEnumDisplayMonitors] then
  398.   begin
  399.     @EnumDisplayMonitors := InitAnApi(mmEnumDisplayMonitors, @EnumDisplayMonitors, 'EnumDisplayMonitors');
  400.     Result := EnumDisplayMonitors(hdcOptionalForPainting, lprcEnumMonitorsThatIntersect, lpfnEnumProc, dwData);
  401.     Exit;
  402.   end;
  403.  
  404.   Result := False;
  405.   if not Assigned(lpfnEnumProc) then Exit;
  406.  
  407.   rcLimit.Left := 0;
  408.   rcLimit.Top := 0;
  409.   rcLimit.Right := GetSystemMetrics(SM_CXSCREEN);
  410.   rcLimit.Bottom := GetSystemMetrics(SM_CYSCREEN);
  411.  
  412.   if hdcOptionalForPainting <> 0 then
  413.   begin
  414.     ClipBox := GetClipBox(hdcOptionalForPainting, rcClip);
  415.     if not GetDCOrgEx(hdcOptionalForPainting, ptOrg) then Exit;
  416.     OffsetRect(rcLimit, -ptOrg.x, -ptOrg.y);
  417.     if not (IntersectRect(rcLimit, rcLimit, rcClip) and
  418.       (lprcEnumMonitorsThatIntersect = nil) or
  419.       IntersectRect(rcLimit, rcLimit, lprcEnumMonitorsThatIntersect^)) then
  420.       begin
  421.         if ClipBox = NULLREGION then Result := True;
  422.         Exit;
  423.       end;
  424.    end else
  425.      if (lprcEnumMonitorsThatintersect <> nil) and
  426.        (not IntersectRect(rcLimit, rcLimit, lprcEnumMonitorsThatIntersect^)) then
  427.        begin
  428.          Result := True;
  429.          Exit;
  430.        end;
  431.    Result := lpfnEnumProc( xPRIMARY_MONITOR, hdcOptionalForPainting, @rcLimit, dwData);
  432. end;
  433.  
  434. procedure InitMultiMonStubs;
  435. begin
  436.   User32Dll := GetModuleHandle(sUser32);
  437.   @GetSystemMetrics := @_GetSystemMetrics;
  438.   @MonitorFromWindow := @xMonitorFromWindow;
  439.   @MonitorFromRect := @xMonitorFromRect;
  440.   @MonitorFromPoint := @xMonitorFromPoint;
  441.   {procedure}@GetMonitorInfoA := @xGetMonitorInfoA;
  442.   {procedure}@GetMonitorInfoW := @xGetMonitorInfoW;
  443.   {procedure}@GetMonitorInfo := @xGetMonitorInfo;
  444.   @EnumDisplayMonitors := @xEnumDisplayMonitors;
  445. end;
  446.  
  447. initialization
  448.   InitMultiMonStubs;
  449.  
  450. end.
  451.