Ejemplo n.º 1
0
bool DebugScreen( void )
{
    if( !WndMain ) return( FALSE );
    if( FocusWnd && WinIsWindow( GUIGetHAB(), FocusWnd ) &&
        FocusWnd != WinQueryFocus( HWND_DESKTOP, 0 ) ) {
        WinSetFocus( HWND_DESKTOP, FocusWnd );
    }
    if( ActiveWnd && WinIsWindow( GUIGetHAB(), ActiveWnd ) &&
        ActiveWnd != WinQueryActiveWindow( HWND_DESKTOP, 0 ) ) {
        WinSetActiveWindow( HWND_DESKTOP, ActiveWnd );
    }
    return( FALSE );
}
Ejemplo n.º 2
0
BOOL launchPad::lpSetLaunchPadPos(HWND hwndInsertBehind, LONG x, LONG y, LONG cx, LONG cy, ULONG fl)
{
  if(WinIsWindow(WinQueryAnchorBlock(hwndLaunchPad), hwndPrevious)) {
    SWP swp;
    WinQueryWindowPos(hwndPrevious,&swp);
    return WinSetWindowPos(hwndLaunchPad, hwndInsertBehind, swp.x+swp.cx+x, y, cx, cy, fl);
  }
  else
    return WinSetWindowPos(hwndLaunchPad, hwndInsertBehind, x, y, cx, cy, fl);
}
/*--------------------------------------------------
 * Destroys the window
 *--------------------------------------------------*/
PMWindow& PMWindow::destroy()
{
  // Prevent recursive destroying
  win_wrapper = TRUE;

  if( WinIsWindow( PMGUI::hab(), handle()))
    if( !WinDestroyWindow( handle()))
      PM_THROW_GUIERROR();

  return *this;
}
/*--------------------------------------------------
 * Stop handling events
 *-------------------------------------------------*/
PMWindow& PMWindow::stop_handling_events()
{
  if( WinIsWindow( PMGUI::hab(), handle()))
  {
    if( !WinSetWindowPtr( handle(), 0, 0 ))
      PM_THROW_GUIERROR();

    if( WinSubclassWindow( handle(), win_default_handler ) == 0 )
      PM_THROW_GUIERROR();
  }
  return *this;
}
Ejemplo n.º 5
0
BOOL CPlugin::initEmbed(ULONG dwInitData)
{
  restorePreferences();

  HWND hWndParent = (HWND)dwInitData;

  if(WinIsWindow((HAB)0, hWndParent))
    m_hWndParent = hWndParent;

  WinLoadDlg(m_hWndParent, m_hWndParent, (PFNWP)TesterDlgProc, m_hInst, IDD_DIALOG_TESTER, (PVOID)this);

  m_bPluginReady = (m_hWnd != NULL);

  return m_bPluginReady;
}
// Window - окно, которое надо проверить.
BYTE WindowTypes_WindowIsPresent( HWND Window )
{
 // Проверяем, есть ли вообще такое окно.
 if( Window == NULLHANDLE ) return 0;
 if( !WinIsWindow( WinQueryAnchorBlock( Window ), Window ) ) return 0;

 // Проверяем, видимо ли оно.
 if( !WinIsWindowVisible( Window ) ) return 0;

 // Узнаем размер окна.
 RECT Rectangle = {0}; WinQueryWindowRect( Window, &Rectangle );

 // Проверяем его.
 if( Rectangle.yTop <= 1 || Rectangle.xRight <= 1 ) return 0;

 // Возврат.
 return 1;
}
// Frame_window - текстовое окно.
VOID Clipper_EndVIOMarkingAndCopyText( HWND Frame_window )
{
 // Узнаем окно картинки.
 HWND SysMenu_window = WinWindowFromID( Frame_window, FID_SYSMENU );

 // Если окна нет - возврат.
 if( !WinIsWindow( WinQueryAnchorBlock( SysMenu_window ), SysMenu_window ) ) return;

 // Если в меню есть строки для включения выделения:
 if( MenuItemIsPresent( SysMenu_window, SM_VIO_MARK ) &&
     MenuItemIsPresent( SysMenu_window, SM_VIO_MOUSE ) )
  {
   // Если обе строки меню для включения выделения выбраны:
   if( MenuItemIsChecked( SysMenu_window, SM_VIO_MARK ) &&
       MenuItemIsChecked( SysMenu_window, SM_VIO_MOUSE ) )
    {
     // Запоминаем выделенный текст. При этом строка для включения выделения должна перестать быть включенной.
     if( MenuItemIsPresent( SysMenu_window, SM_VIO_COPY ) )
      WinSendMsg( Frame_window, WM_SYSCOMMAND, (MPARAM) SM_VIO_COPY, MPFROM2SHORT( CMDSRC_MENU, 0 ) );

     // Выключаем выделение с помощью мыши.
     WinSendMsg( Frame_window, WM_SYSCOMMAND, (MPARAM) SM_VIO_MOUSE, MPFROM2SHORT( CMDSRC_MENU, 0 ) );
     WinSendMsg( SysMenu_window, MM_SETITEMATTR, MPFROM2SHORT( SM_VIO_MOUSE, INCLUDE_SUBMENUS ), MPFROM2SHORT( MIA_CHECKED, 0 ) );

     // Если строка меню для включения выделения все еще выбрана:
     if( MenuItemIsChecked( SysMenu_window, SM_VIO_MARK ) )
      {
       // Выключаем выделение с помощью клавиатуры.
       WinSendMsg( Frame_window, WM_SYSCOMMAND, (MPARAM) SM_VIO_MARK, MPFROM2SHORT( CMDSRC_MENU, 0 ) );
       WinSendMsg( SysMenu_window, MM_SETITEMATTR, MPFROM2SHORT( SM_VIO_MARK, INCLUDE_SUBMENUS ), MPFROM2SHORT( MIA_CHECKED, 0 ) );
      }
    }
  }

 // Возврат.
 return;
}
Ejemplo n.º 8
0
/*-------------------------------------------------------------------------
                            ActMsgContextMenu
--------------------------------------------------------------------------*/
MRESULT ActMsgContextMenu( WNDATTR *wndattr, USHORT x, USHORT y )
{
 BOOL state;

   if (Popup == NULLHANDLE)
      return MRFROMSHORT( TRUE );

   if (MateScrollWnd != NULLHANDLE) {
      if (WinIsWindow( wndattr->hab, MateScrollWnd ) == FALSE)
         MateScrollWnd = NULLHANDLE;
   }

   state = (LPListMarkedLines( wndattr->list ) == 0);
   SetAttr( CMD_COPY, MIA_DISABLED, state );
   SetAttr( CMD_UNMARK, MIA_DISABLED, state );
   SetAttr( CMD_REARRANGE, MIA_DISABLED, state );

   WinOpenClipbrd( wndattr->hab );
   state = (WinQueryClipbrdData( wndattr->hab, CF_TEXT ) == 0);
   WinCloseClipbrd( wndattr->hab );
   SetAttr( CMD_PASTE, MIA_DISABLED, state );

   state = (WinQueryClipbrdViewer( wndattr->hab ) == wndattr->Client);
   SetAttr( CMD_ACCUM, MIA_CHECKED, state );

   state = (MateScrollWnd != NULLHANDLE);
   SetAttr( CMD_MATE, MIA_CHECKED, state );

   WinPopupMenu( wndattr->Frame,
                 wndattr->Frame,
                 Popup,
                 x, y, CMD_ABOUT,
                 PU_HCONSTRAIN | PU_VCONSTRAIN | PU_POSITIONONITEM |
                 PU_KEYBOARD | PU_MOUSEBUTTON1 | PU_MOUSEBUTTON2 );

   return MRFROMSHORT( FALSE );
}
/****************************************************************\
 *  Main routine
 *--------------------------------------------------------------
 *
 *  Name:   main()
 *
 *  Purpose: Initializes the PM environment, calls the
 *              initialization routine, creates the main
 *              window,  and polls the message queue
 *
 *  Usage:
 *
 *  Method:
 *          - obtains anchor block handle and creates message
 *              queue
 *          - calls the initialization routine
 *          - creates the main frame window which creates the
 *              main client window
 *          - polls the message queue via Get/Dispatch Msg loop
 *          - upon exiting the loop, exits
 *
 *  Returns:
 *          0 - if successful execution completed
 *          1 - if error
\****************************************************************/
INT main(int argc, char *argv[])
{
   QMSG        qmsg;          /* message structure */
   static int  iTimeOut = THRD_EXIT_TIMEOUT;

   hab = WinInitialize(0UL);

   if(!hab)
   {
      DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
      return RETURN_ERROR;
   }

   hmq = WinCreateMsgQueue(hab, 0L);

   if(!hmq)
   {
      DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
      WinTerminate(hab);
      return RETURN_ERROR;
   }

   if(!Init(argc, argv))
   {
      if(hwndMainFrame == NULLHANDLE)
      {
          MessageBox(HWND_DESKTOP,
                     IDMSG_MAINWINCREATEFAILED,
                     MB_OK | MB_ERROR,
                     TRUE);
      }

      else
      {
         MessageBox(HWND_DESKTOP,
                    IDMSG_INITFAILED,
                    MB_OK | MB_ERROR,
                    TRUE);

      }

      DosBeep(BEEP_WARN_FREQ, BEEP_WARN_DUR);
      if (WinIsWindow(hab, hwndMainFrame))
      {
         WinDestroyWindow(hwndMainFrame);
      }
      WinDestroyMsgQueue(hmq);
      WinTerminate(hab);
      return RETURN_ERROR;
   }

   /* Get-Dispatch Message loop */
   while(WinGetMsg(hab, &qmsg, NULLHANDLE, 0UL, 0UL))
      WinDispatchMsg(hab, &qmsg);


   /* destroy the help instance */
   DestroyHelpInstance();

   if (WinIsWindow(hab, hwndMainFrame))
      WinDestroyWindow(hwndMainFrame);
   WinDestroyMsgQueue(hmq);

   /* give other thread a chance to exit */
   while (!fThrdsDead && iTimeOut--)
   {
      DosSleep(0UL);
   }

   WinTerminate(hab);
   return RETURN_SUCCESS;

}   /* main() */
// Message определяет пришедшее сообщение.
VOID Changer_ChangerMessageProcessing( PQMSG Message )
{
 // Устанавливаем приоритет потока.
 if( Message->msg == SM_PRIORITY )
  {
   // Устанавливаем приоритет.
   LONG Class = (LONG) Message->mp1;
   LONG Delta = (LONG) Message->mp2;
   DosSetPriority( PRTYS_THREAD, Class, Delta, 0 );

   // Запоминаем приоритет.
   Enhancer.Modules.Changer->Priority = MAKELONG( Class, Delta );
  }

 // Меняем значок окна.
 if( Message->msg == SM_CHANGE_ICON )
  {
   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;
   // Узнаем значок, который должен быть установлен.
   HPOINTER New_icon = (HPOINTER) Message->mp2;

   // Если окна рамки нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Меняем значок.
   Changer_ChangeWindowIcon( Frame_window, New_icon );
  }

 // Сбрасываем значок, который был загружен с диска.
 if( Message->msg == SM_FREE_FILE_ICON )
  {
   // Узнаем значок.
   HPOINTER Icon = (HPOINTER) Message->mp1;

   // Освобождаем память.
   WinFreeFileIcon( Icon );
  }

 // Делаем окно доступным или недоступным для переключения.
 if( Message->msg == SM_SET_JUMPABLE )
  {
   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если окна рамки нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Узнаем свойство.
   ULONG Jumpable = (ULONG) Message->mp2;

   // Меняем его.
   if( Frame_window != GetDetectedShellWindow() ) SetJumpableFlag( Frame_window, Jumpable );
  }

 // Меняем шрифт для текстовых окон - первый и второй шаги.
 if( Message->msg == SM_CHANGE_VIO_FONT || Message->msg == SM_APPLY_VIO_FONT )
  {
   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если шрифт менять не надо - возврат.
   if( !VIOFontMustBeChanged( Frame_window ) ) return;

   // Если окна рамки нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Шаг первый: вызываем окно смены шрифта и ждем его появления.
   if( Message->msg == SM_CHANGE_VIO_FONT )
    {
     // Проверяем состояние окна.
     BYTE VIO_font_dialog = 0; FindProperty( Frame_window, PRP_VIO_FONT_DIALOG, &VIO_font_dialog );
     // Если для этого окна уже был вызван диалог выбора шрифта - возврат.
     if( VIO_font_dialog ) return;

     // Вызываем окно смены шрифта.
     OpenVIOFontMetricsDialog( Frame_window );

     // Запоминаем, что окно было показано.
     VIO_font_dialog = 1; SetProperty( Frame_window, PRP_VIO_FONT_DIALOG, &VIO_font_dialog );
    }

   // Шаг второй: выбираем в нем шрифт и применяем его.
   if( Message->msg == SM_APPLY_VIO_FONT )
    {
     // Выбираем шрифт.
     SubmitVIOFontMetricsDialog( Frame_window );
    }
  }

 // Делаем окно видимым.
 if( Message->msg == SM_SHOW_AND_ARRANGE )
  {
   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если окна рамки нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Делаем окно видимым.
   if( !WinIsWindowVisible( Frame_window ) ) WinShowWindow( Frame_window, 1 );

   // Если надо выравнивать текстовые окна:
   if( ArrangeVIOWindows() )
    {
     // Посылаем в окно сообщение WM_MARK. Когда оно будет получено, окно можно будет выравнивать.
     WinPostMsg( Frame_window, WM_MARK, (MPARAM) MRK_ARRANGE_WINDOW, (MPARAM) SM_ARRANGE_VIO );
    }
  }

 // Возврат.
 return;
}
// Message определяет пришедшее сообщение.
VOID Clipper_ClipperMessageProcessing( PQMSG Message )
{
 // Устанавливаем приоритет потока.
 if( Message->msg == SM_PRIORITY )
  {
   // Устанавливаем приоритет.
   LONG Class = (LONG) Message->mp1;
   LONG Delta = (LONG) Message->mp2;
   DosSetPriority( PRTYS_THREAD, Class, Delta, 0 );

   // Запоминаем приоритет.
   Enhancer.Modules.Clipper->Priority = MAKELONG( Class, Delta );
  }

 // Включаем выделение в текстовом окне.
 if( Message->msg == SM_BEGIN_VIO_MARKING || Message->msg == SM_END_VIO_MARKING )
  {
   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Включаем и выключаем выделение.
   if( Message->msg == SM_BEGIN_VIO_MARKING ) Clipper_BeginVIOMarking( Frame_window );
   if( Message->msg == SM_END_VIO_MARKING ) Clipper_EndVIOMarkingAndCopyText( Frame_window );
  }

 // Запоминаем выделенный текст.
 if( Message->msg == SM_COPY_VIO_TEXT )
  {
   // Если в текстовых окнах не надо запоминать текст - возврат.
   if( !Clipper.Settings.Mouse_in_VIO ) return;

   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Если выделение текста еще не начато - начинаем его.
   if( !Clipper_VIOMarkingIsInProcess( Frame_window ) ) Clipper_BeginVIOMarking( Frame_window );
   // Иначе - завершаем выделение и запоминаем текст.
   else Clipper_EndVIOMarkingAndCopyText( Frame_window );
  }

 // Вставляем текст в окно.
 if( Message->msg == SM_PASTE_VIO_TEXT )
  {
   // Если в текстовых окнах не надо запоминать текст - возврат.
   if( !Clipper.Settings.Mouse_in_VIO ) return;

   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Если в окне не идет выделение текста - вставляем текст.
   if( !Clipper_VIOMarkingIsInProcess( Frame_window ) ) Clipper_PasteTextToVIOWindow( Frame_window );
  }

 // Запоминаем текст при нажатии средней кнопки мыши.
 if( Message->msg == SM_MB_CLICK )
  {
   // Узнаем окно, с которым работает пользователь.
   HWND Input_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Input_window ), Input_window ) ) return;

   // Узнаем окно рабочего стола.
   HWND Desktop = QueryDesktopWindow();

   // Узнаем время, достаточное для двойного нажатия на кнопку мыши.
   LONG DblClk_delta = WinQuerySysValue( Desktop, SV_DBLCLKTIME );

   // Выполняем задержку, чтобы избежать двойного нажатия.
   while( 1 )
    {
     // Если время последнего нажатия на среднюю кнопку мыши неизвестно - произошло двойное нажатие, возврат.
     // В это время в очереди потока уже лежит следующее сообщение - SM_MB_DOUBLECLICK.
     if( WMMBDownTime() == 0 )
      {
       // Освобождаем указатель мыши.
       ResetPointer();

       // Возврат.
       return;
      }

     // Узнаем текущее время.
     LONG Current_time = WinGetCurrentTime( Enhancer.Application );

     // Если прошло достаточно много времени - все в порядке.
     if( Current_time > WMMBDownTime() )
      if( Current_time - WMMBDownTime() > DblClk_delta )
       break;

     // Если время прошло через ноль - возврат.
     if( Current_time < WMMBDownTime() )
      {
       // Освобождаем указатель мыши.
       ResetPointer();

       // Возврат.
       return;
      }

     // Через некоторое время - устанавливаем указатель мыши "прозрачная стрелка".
     if( Current_time - WMMBDownTime() > ( DblClk_delta / 2 ) )
      if( Resources.Pointer_for_CopyPaste != NULLHANDLE )
       WinSetPointer( QueryDesktopWindow(), Resources.Pointer_for_CopyPaste );

     // Выполняем задержку.
     Retard();
    }

   // Освобождаем указатель мыши.
   ResetPointer();

   // Время последнего нажатия на среднюю кнопку мыши - неизвестно.
   DiscardWMMBDownTime();

   // Узнаем ускоритель для этого окна.
   LONG Accelerator = (LONG) Message->mp2;

   // Запоминаем текст в окне.
   ClipboardMouseAction( Input_window, MOUSE_CLIPBOARD_COPY, Accelerator );
  }

 // Вставляем текст в окно при нажатии средней кнопки мыши.
 if( Message->msg == SM_MB_DOUBLECLICK )
  {
   // Узнаем окно, с которым работает пользователь.
   HWND Input_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Input_window ), Input_window ) ) return;

   // Если кнопка мыши снова была нажата - возврат.
   if( WMMBDownTime() ) return;

   // Узнаем ускоритель для этого окна.
   LONG Accelerator = (LONG) Message->mp2;

   // Вставляем текст в окно.
   ClipboardMouseAction( Input_window, MOUSE_CLIPBOARD_PASTE, Accelerator );
  }

 // Вставляем текст в окно Mozilla при нажатии FireFox-клавиши.
 if( Message->msg >= SM_FFX_PASTE_FIRST && Message->msg <= SM_FFX_PASTE_LAST )
  {
   // Узнаем окно, с которым работает пользователь.
   HWND Input_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Input_window ), Input_window ) ) return;

   // Вставляем текст в окно.
   Clipper_PasteFireFoxCharacters( Input_window, Message->msg );
  }

 // Восстанавливаем содержимое Clipboard.
 if( Message->msg == SM_RESTORE_CLIPBOARD ) Clipper_RestoreClipboard();

 // Возврат.
 return;
}
// Message определяет пришедшее сообщение.
VOID Diver_DiverMessageProcessing( PQMSG Message )
{
 // Устанавливаем приоритет потока.
 if( Message->msg == SM_PRIORITY )
  {
   // Устанавливаем приоритет.
   LONG Class = (LONG) Message->mp1;
   LONG Delta = (LONG) Message->mp2;
   DosSetPriority( PRTYS_THREAD, Class, Delta, 0 );

   // Запоминаем приоритет.
   Enhancer.Modules.Diver->Priority = MAKELONG( Class, Delta );
  }

 // Узнаем свойства окна.
 if( Message->msg == SM_QUERY_PROPERTIES )
  {
   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если окна рамки нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Узнаем, какое свойство надо узнать.
   ULONG Target = (ULONG) Message->mp2;

   // Узнаем значок и ширину рамки окна.
   if( Target & WT_UNKNOWN || Target & WT_SYSMENU )
    Diver_QueryWindowProperty( Frame_window, WT_SYSMENU );

   // Если окно заголовка было перерисовано - узнаем заголовок.
   if( Target & WT_UNKNOWN || Target & WT_TITLEBAR ) Diver_QueryWindowProperty( Frame_window, WT_TITLEBAR );

   // Если заголовок есть, но он еще не определен - узнаем его, когда перерисовывается рамка.
   if( Target & WT_BORDER )
    {
     // Узнаем окно заголовка.
     HWND TitleBar_window = WinWindowFromID( Frame_window, FID_TITLEBAR );

     // Если оно есть:
     if( TitleBar_window != NULLHANDLE )
      {
       // Узнаем, есть ли в списке заголовок окна.
       CHAR Title[ SIZE_OF_TITLE ] = ""; FindProperty( Frame_window, PRP_TITLE, Title );

       // Если его нет - узнаем его.
       if( Title[ 0 ] == 0 ) Diver_QueryWindowProperty( Frame_window, WT_TITLEBAR, NO_ACTION, 1 );
      }
    }

   // Узнаем состояние кнопок в правом верхнем углу окна.
   // Проверять кнопки при Target == WT_TITLEBAR нельзя - может
   // возникнуть постоянное рисование, которое выглядит как "мигание" рамки.
   if( Target & WT_UNKNOWN || Target & WT_SYSMENU ) Diver_QueryWindowProperty( Frame_window, WT_MINMAX );

   // Если состояние кнопок еще не определено - узнаем его, когда перерисовывается рамка.
   if( Target & WT_BORDER )
    {
     // Узнаем, есть ли в списке состояние кнопок.
     BYTE Actions_are_detected = 0; FindProperty( Frame_window, PRP_ACTIONS, &Actions_are_detected );

     // Если его нет - узнаем его.
     if( !Actions_are_detected ) Diver_QueryWindowProperty( Frame_window, WT_MINMAX );
    }
  }

 // Проверяет состояние всех окон, когда одно из окон становится выбранным.
 if( Message->msg == SM_CHECK_CONTROLS )
  {
   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если окна рамки нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Проверяем состояние кнопок в окнах приложения, а также их значки.
   Diver_CheckWindowControls( Frame_window );

   // Если окно не перестало быть выбранным - проверяем, нет ли в списке двух одновременно выбранных окон.
   // Для окон диалога эту проверку выполнять не надо - они всегда работают правильно.
   if( WindowIsActive( Frame_window ) )
    if( !WindowIsAppDialog( Frame_window ) )
     CheckActivityProperties( Frame_window );
  }

 // Проверяем рамки окон постоянного размера.
 if( Message->msg == SM_CHECK_FRAME )
  {
   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;
   // Узнаем окно, которое надо проверить.
   HWND Window = (HWND) Message->mp2;

   // Если одного из окон нет - возврат.
   HAB Application = WinQueryAnchorBlock( Frame_window );
   if( !WinIsWindow( Application, Frame_window ) ) return;
   if( !WinIsWindow( Application, Window ) ) return;

   // Выполняем проверку.
   Diver_CheckWindowFrame( Frame_window, Window );
  }

 // Возврат.
 return;
}
// Message определяет пришедшее сообщение. Thread - поток.
VOID Painter_PainterMessageProcessing( PQMSG Message, HAB Thread )
{
 // Устанавливаем приоритет потока.
 if( Message->msg == SM_PRIORITY )
  {
   // Устанавливаем приоритет.
   LONG Class = (LONG) Message->mp1;
   LONG Delta = (LONG) Message->mp2;
   DosSetPriority( PRTYS_THREAD, Class, Delta, 0 );

   // Запоминаем приоритет.
   Enhancer.Modules.Painter->Priority = MAKELONG( Class, Delta );
  }

 // Перерисовываем рамки окон.
 if( Message->msg == SM_DRAW_FRAME )
  {
   // Если рисование отключено - возврат.
   if( !Painter.Settings.Draw_frames ) return;

   // Кеш второго уровня: объединяем несколько заданий в одно.
   {
    // Ставим задание в список.
    Painter.RTSettings.Demand[ 0 ].Frame_window = (HWND) Message->mp1;
    Painter.RTSettings.Demand[ 0 ].Target = (ULONG) Message->mp2;

    // Забираем следующие задания из очереди и ставим их в список.
    INT Demand_total = 1;

    for( INT Count = 1; Count < PAINTER_DEMAND_TABLE; Count ++ )
     {
      QMSG Next_message = {0};
      WinPeekMsg( Thread, &Next_message, NULLHANDLE, SM_DRAW_FRAME, SM_DRAW_FRAME, PM_REMOVE );

      if( Next_message.msg )
       {
        Painter.RTSettings.Demand[ Count ].Frame_window = (HWND) Next_message.mp1;
        Painter.RTSettings.Demand[ Count ].Target = (ULONG) Next_message.mp2;

        Demand_total ++;
       }
      else
       {
        break;
       }
     }

    // Просматриваем составленный список и выполняем рисование.
    for( Count = 0; Count < Demand_total; Count ++ )
     {
      // Узнаем окно рамки.
      HWND Frame_window = Painter.RTSettings.Demand[ Count ].Frame_window;
      // Если в списке нет значения - продолжаем перебор.
      if( Frame_window == NULLHANDLE ) continue;

      // Узнаем, какое окно надо перерисовать.
      ULONG Target = Painter.RTSettings.Demand[ Count ].Target;

      // Пробегаем список до конца и забираем задания для того же окна.
      if( Demand_total > 1 )
       if( Count != Demand_total - 1 )
        {
         for( INT Position = Count + 1; Position < Demand_total; Position ++ )
          if( Painter.RTSettings.Demand[ Position ].Frame_window == Frame_window )
           {
            Target = Target | Painter.RTSettings.Demand[ Position ].Target;
            Painter.RTSettings.Demand[ Position ].Frame_window = NULLHANDLE;
           }
        }

      // Если окна нет - продолжаем перебор.
      if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) continue;

      // Перерисовываем рамку, применяя "общее задание".
      Painter_DrawWindowFrame( Frame_window, Target );
     }
   }
  }

 // Перерисовываем картинку в левом верхнем углу окна.
 if( Message->msg == SM_DRAW_SYSMENU )
  {
   // Если рисование отключено - возврат.
   if( !Painter.Settings.Draw_frames ) return;

   // Узнаем окно картинки.
   HWND SysMenu_window = (HWND) Message->mp1;

   // Если окна нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( SysMenu_window ), SysMenu_window ) ) return;

   // Узнаем, нажата ли картинка.
   LONG SysMenu_is_pressed = (LONG) Message->mp2;

   // Находим в списке значок окна.
   HPOINTER Icon = NULLHANDLE;
   HWND Frame_window = WinQueryWindow( SysMenu_window, QW_PARENT );

   FindProperty( Frame_window, PRP_ICON, &Icon );

   // Узнаем размер и расположение окна рамки.
   RECT Frame_rectangle = {0}; SWP Frame_placement = {0};
   Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement );

   // Если значок не найден - закрашиваем окно картинки.
   if( Icon == NULLHANDLE ) Painter_PreDrawControl( SysMenu_window, SYSCLR_BUTTONMIDDLE, 0, Frame_window, &Frame_rectangle, &Frame_placement );
   // Иначе - рисуем картинку.
   else Painter_DrawSystemMenu( SysMenu_window, Frame_window, &Frame_rectangle, &Frame_placement, Icon, FT_UNKNOWN, SysMenu_is_pressed );
  }

 // Перерисовываем кнопки.
 if( Message->msg == SM_DRAW_BUTTONS )
  {
   // Если рисование отключено - возврат.
   if( !Painter.Settings.Draw_frames ) return;

   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если окна рамки нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Узнаем, как выглядит рамка окна.
   LONG Frame_type = FrameType( Frame_window );

   // Узнаем окно заголовка.
   HWND TitleBar_window = WinWindowFromID( Frame_window, FID_TITLEBAR );

   // Узнаем размер и расположение окна рамки.
   RECT Frame_rectangle = {0}; SWP Frame_placement = {0};
   Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement );

   // Рисуем кнопки.
   Painter_DrawButtons( Frame_window, Frame_type, &Frame_rectangle, &Frame_placement, TitleBar_window );
  }

 // Задаем подходящее расположение для окна картинки и кнопок.
 if( Message->msg == SM_PREPARE_CONTROLS )
  {
   // Узнаем окно рамки.
   HWND Frame_window = (HWND) Message->mp1;

   // Если окна рамки нет - возврат.
   if( !WinIsWindow( WinQueryAnchorBlock( Frame_window ), Frame_window ) ) return;

   // Узнаем размер и расположение окна.
   RECT Frame_rectangle = {0}; SWP Frame_placement = {0};
   Painter_QueryFrameRectangeAndPlacement( Frame_window, &Frame_rectangle, &Frame_placement );

   // Задаем правильное расположение окна картинки, заголовка и других окон.
   // При этом окно рамки получит одно сообщение WM_PAINT вместо нескольких.
   Painter_PrepareWindowControls( Frame_window, FT_UNKNOWN, &Frame_rectangle, &Frame_placement, NULLHANDLE, NULLHANDLE, NULLHANDLE );
  }

 // Обновляем окно.
 if( Message->msg == SM_UPDATE_FRAME ) UpdateWindow( (HWND) Message->mp1 );

 // Обновляем все окна.
 if( Message->msg == SM_UPDATE_ALL_FRAMES )
  {
   // Перерисовываем рамки всех окон.
   UpdateAllWindows( QueryDesktopWindow() );
  }

 // Возврат.
 return;
}