// Frame_window - окно приложения, Class и Delta - значения приоритета.
VOID Priority_SetPriorityLevel( HWND Frame_window, LONG Class, LONG Delta )
{
 // Если это окно создано самой оболочкой Presentation Manager - возврат.
 if( IsPMShellAuxiliaryWindow( Frame_window ) ) return;

 // Узнаем приложение, создавшее окно.
 // Для окон VIO здесь возвращается их настоящий PID, а не PID окна (оно создаётся оболочкой PM).
 PID Process_ID = QueryWindowRealProcessID( Frame_window );

 // Пробуем изменить приоритет на месте.
 APIRET Result = NO_ERROR; if( Process_ID != 0 ) Result = DosSetPriority( PRTYS_PROCESSTREE, Class, Delta, Process_ID );

 // Если это сделать не удалось:
 if( Result != NO_ERROR )
  {
   // Запоминаем значения приоритета для окна.
   SetProperty( Frame_window, PRP_PRIORITY_CLASS, &Class );
   SetProperty( Frame_window, PRP_PRIORITY_DELTA, &Delta );

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

   // Посылаем в очередь окна рабочего стола сообщение WM_MARK. Приоритет можно будет изменить во время его получения.
   HMQ Desktop_queue = WinQueryWindowULong( Desktop, QWL_HMQ );
   WinPostQueueMsg( Desktop_queue, WM_MARK, (MPARAM) MRK_SET_PRIORITY, (MPARAM) Frame_window );

   // Посылаем такое же сообщение в очередь окна. Текстовые окна используют ту же очередь, что и окно рабочего стола, поэтому второй раз посылать им сообщение не надо.
   HMQ Window_queue = WinQueryWindowULong( Frame_window, QWL_HMQ );
   if( Window_queue != Desktop_queue ) WinPostQueueMsg( Window_queue, WM_MARK, (MPARAM) MRK_SET_PRIORITY, (MPARAM) Frame_window );
  }

 // Возврат.
 return;
}
// Все переменные - внешние.
VOID ApplierSendMsgHook( HAB Application, PSMHSTRUCT Message )
{
 // Если надо выполнять действия с окнами диалогов:
 if( Applier.Settings.Script_after_Logon || Applier.Settings.Remember_dialog_fields || Applier.Settings.Send_Yes ) if( !RoomsChangeIsInProcess() )
  {
   // Если окно рамки становится видимым:
   if( TopFrameWindowIsShowing( Message ) )
    {
     // Узнаем окно рамки.
     HWND Frame_window = QueryFrameWindow( Message->hwnd );

     // Если такое окно содержит поля для ввода пароля и их значения надо забрать:
     if( Applier.Settings.Script_after_Logon ) if( Applier_WindowIsPresentInLogonDialogList( Frame_window, 0 ) )
      {
       // Посылаем в очередь сообщение WM_MARK. Когда оно будет получено, окно подготовит все свои кнопки и можно будет проверять его заголовок.
       HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ );
       WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_LOGON_WINDOW, (MPARAM) Frame_window );
      }

     // Если в таком окне надо заполнять поля при его появлении:
     if( Applier.Settings.Remember_dialog_fields ) if( Applier_WindowIsPresentInIncompleteDialogList( Frame_window, 0 ) )
      {
       // Посылаем в очередь сообщение WM_MARK. Когда оно будет получено, окно подготовит все свои кнопки и можно будет проверять его заголовок.
       HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ );
       WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_COMPLETE_DIALOG, (MPARAM) Frame_window );
      }

     // Если это окно надо закрывать при появлении:
     if( Applier.Settings.Send_Yes ) if( Applier_WindowIsPresentInMessageDialogList( Frame_window, 0 ) )
      {
       // Посылаем в очередь сообщение WM_MARK. Когда оно будет получено, окно подготовит все свои кнопки и можно будет проверять его заголовок.
       HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ );
       WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_SEND_YES, (MPARAM) Frame_window );
      }
    }

   // Если есть окна для ввода пароля и одно из окон закрывается:
   if( Applier.RTSettings.Logon_in_process ) if( Message->msg == WM_DESTROY )
    {
     // Если окно есть в списке отслеживаемых окон:
     for( INT Count = APPLIER_MONITORING_LOGON_WINDOWS - 1; Count >= 0; Count -- )
      if( Applier.RTDlgMemory.Logon_windows[ Count ].Window == Message->hwnd )
       {
        // Посылаем сообщение в поток. Он выполнит все необходимые проверки.
        WinPostQueueMsg( Enhancer.Modules.Applier->Message_queue, SM_LOGON_ACTION, (MPARAM) Message->hwnd, 0 );
        break;
       }
    }

   // Если есть окна для ввода пароля и одно из окон становится выбранным:
   if( Applier.RTSettings.Logon_in_process ) if( TopFrameWindowIsActivating( Message ) )
    {
     // Посылаем в поток сообщение о том, что надо проверить существование окон ввода пароля.
     WinPostQueueMsg( Enhancer.Modules.Applier->Message_queue, SM_LOGON_CHECK, 0, 0 );
    }
  }

 // Возврат.
 return;
}
// Все переменные - внешние.
VOID VIOFontManagerInputHook( HAB Application, PQMSG Message, PBYTE Discarding )
{
 // Меняем шрифты для текстовых окон.
 if( VIOFontManager.Settings.Change_VIO_font_metrics )
  {
   // Устанавливаем шрифт в окне.
   if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_SET_VIO_FONT )
    {
     // Узнаем окно рамки.
     HWND Frame_window = (HWND) Message->mp2;

     // Посылаем сообщение в поток.
     WinPostQueueMsg( Enhancer.Modules.Changer->Message_queue, SM_APPLY_VIO_FONT, (MPARAM) Frame_window, 0 );
    }

   // Делаем окно видимым и выравниваем его по середине экрана.
   if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_SHOW_AND_ARRANGE )
    {
     // Посылаем сообщение в поток.
     HWND Frame_window = (HWND) Message->mp2;
     WinPostQueueMsg( Enhancer.Modules.Changer->Message_queue, SM_SHOW_AND_ARRANGE, (MPARAM) Frame_window, 0 );
    }
  }

 // Возврат.
 return;
}
VOID MMKbdListener_StartThread( VOID )
{
 // Сбрасываем переменную для ответа от потока.
 Thread_responds.Thread_is_created = 0;

 // Если поток уже создан - выход.
 CHAR Semaphore_name[] = "\\SEM32\\NICE-OS2!Krnl!MMKbdListener"; HMTX hmtxAlreadyRunning = NULLHANDLE;
 if( DosOpenMutexSem( Semaphore_name, &hmtxAlreadyRunning ) == NO_ERROR ) return;
 else DosCreateMutexSem( Semaphore_name, &hmtxAlreadyRunning, DC_SEM_SHARED, 1 );

 // Создаем поток.
 APIRET Thread_is_created = DosCreateThread( &Enhancer.Modules.MMKbdListener->Thread, (PFNTHREAD) MMKbdListener_MMKbdListenerThread, 0, 0, THREAD_STACK_SIZE );
 // Если он создан - ждем, пока в нем будет создана очередь сообщений.
 if( Thread_is_created == NO_ERROR ) while( Thread_responds.Thread_is_created == 0 ) { Retard(); }
 // Если поток создать не удалось - возврат.
 if( Thread_is_created != NO_ERROR || Thread_responds.Thread_is_created == -1 ) { Enhancer.Modules.MMKbdListener->Thread = 0; return; }
 // Устанавливаем приоритет потока.
 WinPostQueueMsg( Enhancer.Modules.MMKbdListener->Message_queue, SM_PRIORITY, (MPARAM) PRTYC_REGULAR, (MPARAM) PRTYD_QUICK );

 // Посылаем в поток сообщение о том, что ему следует вызвать функцию ожидания сообщений.
 WinPostQueueMsg( Enhancer.Modules.MMKbdListener->Message_queue, SM_WAIT_MMKBD_EVENTS, 0, 0 );

 // Возврат.
 return;
}
Beispiel #5
0
main(int argc, char *argv[], char *envp[])
{
  HAB hab;
  HMQ hmq;
  QMSG qmsg;
  char  szBuf[MAX_BUF];
  ATOM atom;

  hab = WinInitialize( 0 );
  hmq = WinCreateMsgQueue( hab, 0 );

  atom = WinAddAtom(WinQuerySystemAtomTable(), CLASS_NAME);

  if(Initialize(0, argv[0]))
  {
    WinPostQueueMsg(0, WM_QUIT, 1, 0);
  }
  else if(!InitApplication(0))
  {
    char szEFailed[MAX_BUF];

    if(NS_LoadString(0, IDS_ERROR_FAILED, szEFailed, MAX_BUF) == WIZ_OK)
    {
      sprintf(szBuf, szEFailed, "InitApplication().");
      PrintError(szBuf, ERROR_CODE_SHOW);
    }
    WinPostQueueMsg(0, WM_QUIT, 1, 0);
  }
  else if(ParseUninstallIni(argc, argv))
  {
    WinPostQueueMsg(0, WM_QUIT, 1, 0);
  }
  else if(ugUninstall.bUninstallFiles == TRUE)
  {
    if(diUninstall.bShowDialog == TRUE)
      hDlgUninstall = InstantiateDialog(hWndMain, DLG_UNINSTALL, diUninstall.szTitle, DlgProcUninstall);
    else
      ParseAllUninstallLogs();
  }

  if((ugUninstall.bUninstallFiles == TRUE) && (diUninstall.bShowDialog == TRUE))
  {
    while ( WinGetMsg( hab, &qmsg, NULLHANDLE, 0, 0 ) )
      WinDispatchMsg( hab, &qmsg );
  }

  /* Do clean up before exiting from the application */
  DeInitialize();

  WinDeleteAtom(WinQuerySystemAtomTable(), atom);

  WinDestroyMsgQueue( hmq );
  WinTerminate( hab ); 

}
VOID Launcher_PostQuitMsg( VOID )
{
 // Посылаем сообщение в поток.
 WinPostQueueMsg( Enhancer.Modules.Launcher->Message_queue, WM_QUIT, 0, 0 );

 // Возврат.
 return;
}
// Все переменные - внешние.
VOID ApplierInputHook( HAB Application, PQMSG Message, PBYTE Discarding )
{
 // Если надо выполнять действия с окнами диалогов:
 if( Applier.Settings.Script_after_Logon || Applier.Settings.Remember_dialog_fields || Applier.Settings.Send_Yes )
  {
   // Запоминаем окна ввода пароля. Это сообщение посылается в окно в SendMsgHook() при обработке другого сообщения.
   if( Applier.Settings.Script_after_Logon )
    if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_LOGON_WINDOW )
     {
      // Посылаем сообщение в поток.
      HWND Frame_window = (HWND) Message->mp2;
      WinPostQueueMsg( Enhancer.Modules.Applier->Message_queue, SM_LOGON_WINDOW, (MPARAM) Frame_window, 0 );
     }

   // Запоминаем значения в окнах ввода пароля. Это сообщение посылается в окно в SendMsgHook() при обработке другого сообщения.
   if( Applier.Settings.Script_after_Logon )
    if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_LOGON_VALUES )
     {
      // Посылаем сообщение в поток.
      HWND Frame_window = (HWND) Message->mp2;
      WinPostQueueMsg( Enhancer.Modules.Applier->Message_queue, SM_LOGON_VALUES, (MPARAM) Frame_window, 0 );
     }

   // Восстанавливаем поля ввода в окнах диалогов. Это сообщение посылается в окно в SendMsgHook() при обработке другого сообщения.
   if( Applier.Settings.Remember_dialog_fields )
    if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_COMPLETE_DIALOG )
     {
      // Посылаем сообщение в поток.
      HWND Frame_window = (HWND) Message->mp2;
      WinPostQueueMsg( Enhancer.Modules.Applier->Message_queue, SM_COMPLETE_DIALOG, (MPARAM) Frame_window, 0 );
     }

   // Закрываем окна диалогов. Это сообщение посылается в окно в SendMsgHook() при обработке другого сообщения.
   if( Applier.Settings.Send_Yes )
    if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_SEND_YES )
     {
      // Посылаем сообщение в поток.
      HWND Frame_window = (HWND) Message->mp2;
      WinPostQueueMsg( Enhancer.Modules.Applier->Message_queue, SM_SEND_YES, (MPARAM) Frame_window, 0 );
     }
  }

 // Возврат.
 return;
}
// Frame_window - окно рамки.
VOID Diver_CheckWindowFrameDrawingNode( HWND Frame_window )
{
 // Посылаем сообщение в очередь.
 HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ );
 WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_DRAW_FRAME, (MPARAM) Frame_window );

 // Возврат.
 return;
}
// Все переменные - внешние.
VOID RoomsSendMsgHook( HAB Application, PSMHSTRUCT Message )
{
 // Если надо добавить комнаты к рабочему столу:
 if( Rooms.Settings.Create_Rooms ) if( !RoomsChangeIsInProcess() )
  {
   // Если окно рамки становится выбранным:
   if( TopFrameWindowIsActivating( Message ) )
    {
     // Узнаем окно рамки.
     HWND Frame_window = QueryFrameWindow( Message->hwnd );

     // Запоминаем комнату, в которой располагается окно.
     Rooms_SetRoomProperty( Frame_window, GetCurrentOrNextRoom() );

     // Делаем окно доступным для переключения.
     WinPostQueueMsg( Enhancer.Modules.Changer->Message_queue, SM_SET_JUMPABLE, (MPARAM) Frame_window, (MPARAM) SWL_JUMPABLE );
    }

   // Если используется оболочка WPS:
   if( ShellIsWPS() )
    {
     // Если окно оболочки скрыто:
     if( GetCurrentOrNextRoom() != SHELL_ROOM )
      {
       // Если оно возвращается в обычное состояние или становится выбранным - надо спрятать его.
       if( TopFrameWindowIsMoving( Message ) || TopFrameWindowIsActivating( Message ) )
        {
         // Узнаем окно рамки.
         HWND Frame_window = QueryFrameWindow( Message->hwnd );

         // Если это окно WPS - посылаем в очередь сообщение WM_MARK. Когда оно будет получено, окно можно будет проверить.
         if( IsFolderWindow( Frame_window ) )
          {
           HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ );
           WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_CHECK_WINDOW, (MPARAM) Frame_window );
          }
        }
      }
    }
  }

 // Возврат.
 return;
}
SSMODULEDECLSPEC int SSMODULECALL SSModule_StopSaving(void)
{
  // This is called when we have to stop saving.
#ifdef DEBUG_LOGGING
  AddLog("[SSModule_StopSaving] : Enter!\n");
#endif
  if (!bRunning)
  {
#ifdef DEBUG_LOGGING
    AddLog("[SSModule_StopSaving] : Not running, Leaving.\n");
#endif
    return SSMODULE_ERROR_NOTRUNNING;
  }

#ifdef DEBUG_LOGGING
  AddLog("[SSModule_StopSaving] : Closing saver window\n");
#endif

  // Notify saver thread to stop!
  if (bOnlyPreviewMode)
  {
    // In preview mode, which means that there is no window created, but the
    // window was subclassed. So we cannot close the window, but we have to
    // post the WM_QUIT message into the thread's message queue to notify it
    // that this is the end of its job.
    WinPostQueueMsg(hmqSaverThreadMsgQueue, WM_QUIT, (MPARAM) NULL, (MPARAM) NULL);
  }
  else
  {
    // Close saver window
    WinPostMsg(hwndSaverWindow, WM_QUIT, (MPARAM) NULL, (MPARAM) NULL);
  }

#ifdef DEBUG_LOGGING
  AddLog("[SSModule_StopSaving] : Waiting for thread to die\n");
#endif

  // Wait for the thread to stop
  DosWaitThread(&tidSaverThread, DCWW_WAIT);

#ifdef DEBUG_LOGGING
  AddLog("[SSModule_StopSaving] : Screen saver stopped.\n");
#endif

  // Ok, screensaver stopped.
  bRunning = FALSE;
  free(CfgDlgInit.pchText);
  CfgDlgInit.pchText = NULL;

  return SSMODULE_NOERROR;
}
// Все переменные - внешние.
VOID VIOFontManagerSendMsgHook( HAB Application, PSMHSTRUCT Message )
{
 // Меняем шрифты для текстовых окон.
 if( VIOFontManager.Settings.Change_VIO_font_metrics ) if( !RoomsChangeIsInProcess() )
  {
   // Если окно рамки становится видимым:
   if( TopFrameWindowIsShowing( Message ) )
    {
     // Узнаем окно рамки.
     HWND Frame_window = QueryFrameWindow( Message->hwnd );

     // Если это текстовое окно:
     if( IsVIOWindow( Frame_window ) )
      {
       // Узнаем имя приложения, создавшего окно.
       CHAR Exe_name[ SIZE_OF_NAME ] = ""; GetDetectedExeName( Frame_window, Exe_name );

       // Если его удалось определить:
       if( Exe_name[ 0 ] != 0 )
        {
         // Если в окне надо менять шрифт - посылаем сообщение в поток, который это сделает.
         if( VIOFontManager_VIOFontMustBeChanged( Frame_window ) )
          WinPostQueueMsg( Enhancer.Modules.Changer->Message_queue, SM_CHANGE_VIO_FONT, (MPARAM) Frame_window, 0 );
        }
       // А если оно неизвестно - посылаем сообщение в поток, который подождет его некоторое время.
       else
        {
         WinPostQueueMsg( Enhancer.Modules.VIOMonitor->Message_queue, SM_MONITOR_VIO, (MPARAM) Frame_window, (MPARAM) SM_CHANGE_VIO_FONT );
        }
      }
    }
  }

 // Возврат.
 return;
}
Beispiel #12
0
static void ReleaseThreadQueue( PID pid, TID tid )
{
    HMQ                 hmq;
    int                 i;

    hmq = WinQueueFromID( HabDebugger, pid, tid );
    if( hmq == NULLHANDLE )
        return;
    for( i = 0; i < NumAssumedQueues; ++i ) {
        if( hmq == AssumedQueues[i] ) {
            WinPostQueueMsg( hmq, WM_QUIT, 0, 0 ); // break one soft mode loop
            AssumedQueues[i] = NULLHANDLE;
            break;
        }
    }
}
Beispiel #13
0
/*****************************************************************************
 * Close: destroy KVA video thread output method
 *****************************************************************************
 * Terminate an output method created by Open
 *****************************************************************************/
static void Close ( vlc_object_t *object )
{
    vout_display_t * vd = (vout_display_t *)object;
    vout_display_sys_t * sys = vd->sys;

    WinPostQueueMsg( sys->hmq, WM_QUIT, 0, 0 );

    DosWaitThread( &sys->tid, DCWW_WAIT );

    if( sys->pool )
        picture_pool_Delete( sys->pool );

    DosCloseEventSem( sys->ack_event );

    free( sys );
}
// Все переменные - внешние.
VOID ApplierKbdInputHook( HAB Application, PQMSG Message, PBYTE Discarding )
{
 // Запоминаем значения в окне ввода пароля.
 if( Applier.Settings.Script_after_Logon ) if( Applier.RTSettings.Logon_in_process )
  {
   // Следим за нажатиями на клавиши.
   if( Message->msg == WM_CHAR )
    {
     // Смотрим, какая клавиша нажата.
     BYTE Scan_code = CHAR4FROMMP( Message->mp1 );
     SHORT State = SHORT1FROMMP( Message->mp1 );

     // Если идет отжатие клавиши:
     if( State & KC_KEYUP )
      {
       // Проверяем клавишу.
       BYTE Latin_key = 0;

       if( Scan_code != 0 )
        if( !( State & KC_CTRL ) ) if( !( State & KC_ALT ) )
         Latin_key = 1;

       // Если это латинская клавиша:
       if( Latin_key )
        {
         // Узнаем окно рамки.
         HWND Frame_window = QueryFrameWindow( Message->hwnd );

         // Если оно есть в списке отслеживаемых окон:
         for( INT Count = APPLIER_MONITORING_LOGON_WINDOWS - 1; Count >= 0; Count -- )
          if( Applier.RTDlgMemory.Logon_windows[ Count ].Window == Frame_window )
           {
            // Посылаем в очередь сообщение WM_MARK. Когда оно будет получено, окно подготовит значение в поле ввода.
            HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ );
            WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_LOGON_VALUES, (MPARAM) Frame_window );
            break;
           }
        }
      }
    }
  }

 // Возврат.
 return;
}
// Frame_window - окно рамки, New_icon - новый значок.
VOID Changer_ChangeWindowIcon( HWND Frame_window, HPOINTER New_icon )
{
 // Узнаем значок, который используется сейчас.
 HPOINTER Current_icon = (HPOINTER) WinSendMsg( Frame_window, WM_QUERYICON, 0, 0 );

 // Меняем его.
 if( Current_icon != New_icon )
  {
   // Задаем новый значок.
   WinSendMsg( Frame_window, WM_SETICON, (MPARAM) New_icon, 0 );

   // Посылаем сообщение в поток рисования.
   WinPostQueueMsg( Enhancer.Modules.Painter->Message_queue, SM_DRAW_FRAME, (MPARAM) Frame_window, (MPARAM) WT_SYSMENU );
  }

 // Возврат.
 return;
}
// Message - сообщение, Scan_code - клавиша, Modifiers - клавиши Ctrl, Alt и Shift.
// Post_marker_message означает, что в очередь окна надо направить сообщение WM_MARK.
// Если переменная Message не задана - надо сбросить клавиши в исходное состояние.
VOID KbdState_ChangePMKeyboardState( PQMSG Message, SHORT Scan_code, SHORT Modifiers, BYTE Post_marker_message = 1 )
{
 // Узнаем состояние клавиатуры.
 HWND Desktop = QueryDesktopWindow();

 BYTE Keyboard_state[ 256 ]; bzero( Keyboard_state, sizeof( BYTE ) * 256 );
 WinSetKeyboardStateTable( Desktop, Keyboard_state, 0 );

 // Включаем или выключаем Ctrl, Alt и Shift.
 if( Message != NULL )
  {
   if( Scan_code == SC_INSERT ) Keyboard_state[ VK_INSERT ] = SET_KEY_PRESSED; else Keyboard_state[ VK_INSERT ] = 0;
   if( Scan_code == SC_DELETE ) Keyboard_state[ VK_DELETE ] = SET_KEY_PRESSED; else Keyboard_state[ VK_DELETE ] = 0;
   if( Scan_code == SC_BACKSPACE ) Keyboard_state[ VK_BACKSPACE ] = SET_KEY_PRESSED; else Keyboard_state[ VK_BACKSPACE ] = 0;

   if( Modifiers & KC_CTRL ) Keyboard_state[ VK_CTRL ] = SET_KEY_PRESSED; else Keyboard_state[ VK_CTRL ] = 0;
   if( Modifiers & KC_ALT ) Keyboard_state[ KC_ALT ] = SET_KEY_PRESSED; else Keyboard_state[ KC_ALT ] = 0;
   if( Modifiers & KC_SHIFT ) Keyboard_state[ VK_SHIFT ] = SET_KEY_PRESSED; else Keyboard_state[ VK_SHIFT ] = 0;
  }
 // Или восстанавливаем настоящие значения.
 else
  {
   if( KeyIsPressed( SC_INSERT ) ) Keyboard_state[ VK_INSERT ] = SET_KEY_PRESSED; else Keyboard_state[ VK_INSERT ] = 0;
   if( KeyIsPressed( SC_DELETE ) ) Keyboard_state[ VK_DELETE ] = SET_KEY_PRESSED; else Keyboard_state[ VK_DELETE ] = 0;
   if( KeyIsPressed( SC_BACKSPACE ) ) Keyboard_state[ VK_BACKSPACE ] = SET_KEY_PRESSED; else Keyboard_state[ VK_BACKSPACE ] = 0;

   if( CtrlIsPressed() ) Keyboard_state[ VK_CTRL ] = SET_KEY_PRESSED; else Keyboard_state[ VK_CTRL ] = 0;
   if( AltIsPressed() ) Keyboard_state[ KC_ALT ] = SET_KEY_PRESSED; else Keyboard_state[ KC_ALT ] = 0;
   if( ShiftIsPressed() ) Keyboard_state[ VK_SHIFT ] = SET_KEY_PRESSED; else Keyboard_state[ VK_SHIFT ] = 0;
  }

 // Сбрасываем все сведения о кнопках мыши. Это необходимо при вставке текста с помощью
 // средней кнопки, когда сообщения сбрасываются, и данные, что кнопка нажата, остаются.
 Keyboard_state[ VK_BUTTON1 ] = 0;
 Keyboard_state[ VK_BUTTON2 ] = 0;
 Keyboard_state[ VK_BUTTON3 ] = 0;

 // Устанавливаем новое состояние клавиатуры.
 WinSetKeyboardStateTable( Desktop, Keyboard_state, 1 );

 // Запоминаем, что состояние клавиатуры изменено.
 if( Message != NULL )
  {
   // Запоминаем, что состояние клавиатуры изменено.
   KbdState.Keyboard_state_is_changed = 1;

   // Если в очередь окна надо направить сообщение:
   if( Post_marker_message )
    {
     // Посылаем в очередь окна сообщение WM_MARK. Когда оно будет получено, состояние можно будет вернуть назад.
     HMQ Message_queue = WinQueryWindowULong( Message->hwnd, QWL_HMQ );
     WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_KBD_MODIFIERS, 0 );
    }
  }
 // Или запоминаем, что состояние клавиатуры восстановлено.
 else
  {
   // Запоминаем, что состояние клавиатуры восстановлено.
   KbdState.Keyboard_state_is_changed = 0;
  }

 // Возврат.
 return;
}
Beispiel #17
0
void Draw_Thread(ULONG ulThreadArg)
{
if(!(habDT=WinInitialize(0UL)))         /* Initialize client window */
    GEN_ERR(habDT,hwndFrame,hwndClient);
                                        /* Create a message queue */
if(!(hmqDT=WinCreateMsgQueue(habDT,0UL)))
    GEN_ERR(habDT,hwndFrame,hwndClient);
if(!(hpsDT=WinGetPS(hwndClient)))       /* Get a presentation space for client area */
    GEN_ERR(habDT,hwndFrame,hwndClient);
                                        /* Initialize message queue */
WinPostQueueMsg(hmqDT,DT_PAINT,0UL,0UL);
while(qmsqDT.msg!=DT_EXIT)
    {
    if(WinPeekMsg(habDT,                /* Get the message into message queue */
    &qmsqDT,                            /* Message structure */
    NULLHANDLE,                         /* Window filter (none) */
    0UL,                                /* First message ID */
    0UL,                                /* Last message ID */
    PM_REMOVE)==FALSE)                  /* Options (remove message) */
        qmsqDT.msg=DT_IDLE;             /* If no message available, assume idle */
    switch(qmsqDT.msg)
    {
    case DT_PAINT:                      /* Repaint client window */
        {
        RECTL   rclDT;
        int     x,y;
                                        /* Repaint client window aread */
        WinQueryWindowRect(hwndClient,&rclDT);
        WinFillRect(hpsDT,&rclDT,CLR_WHITE);
        for(x=1;x<RB_X;x++)             /* Draw the entries on playing ground */
            for(y=1;y<RB_Y;y++)
                if(RB_Array[x][y]!=RB_EMPTY)
                    Draw_Bitmap(RB_Array[x][y],ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE);
        break;
        }
    case DT_LBUTTON:
        {
        int     x,y;
                                        /* Left button was pressed, get the location,
                                           add \ to RB_Array, and draw \ bitmap, if
                                           field is emty */
        x=(LONGFROMMP(qmsqDT.mp1)/RB_SIZE)+1;
        y=(LONGFROMMP(qmsqDT.mp2)/RB_SIZE)+1;
        if(RB_Array[x][y]==RB_EMPTY)
            {
            RB_Array[x][y]=RB_LX;
            Draw_Bitmap(RB_LX,ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE);
            }
        break;
        }
    case DT_RBUTTON:
        {
        int     x,y;
                                        /* Right button was pressed, get the location,
                                           add / to RB_Array, and draw / bitmap, if
                                           field is emty */
        x=(LONGFROMMP(qmsqDT.mp1)/RB_SIZE)+1;
        y=(LONGFROMMP(qmsqDT.mp2)/RB_SIZE)+1;
        if(RB_Array[x][y]==RB_EMPTY)
            {
            RB_Array[x][y]=RB_RX;
            Draw_Bitmap(RB_RX,ROP_SRCCOPY,(x-1)*RB_SIZE,(y-1)*RB_SIZE);
            }
        break;
        }
     case DT_IDLE:
        {
        if(runRB==TRUE)
            {
            ULONG       x,y,Symbol;
                                        /* Under DOS we would query the time in milliseconds
                                           from the system timer, to adjust graphics. This
                                           is accurate, but in a multitasking in a multitasking
                                           system, we must assume being pre-empted. Therefore
                                           we can't have an exact time bases. Hope that
                                           the system timer counts more often than all 31
                                           milliseconds in future releases/machines */
                                        /* Draw bitmap */
            switch(RB_Dir)              /* Test that RollBall doesn't leave borders. A
                                           border reverses the direction and produces a
                                           beep */
            {
            case UP:
                RB_PosY++;
                if((RB_PosY+RB_SIZE)>=((RB_Y-2)*RB_SIZE))
                    {
                    RB_PosY=(RB_Y-3)*RB_SIZE;
                    RB_Dir=DOWN;
                    DosBeep(800,50);
                    }
                break;
            case DOWN:
                RB_PosY--;
                if(RB_PosY<0)
                    {
                    RB_PosY=0;
                    RB_Dir=UP;
                    DosBeep(800,50);
                    }
                break;
            case LEFT:
                RB_PosX--;
                if(RB_PosX<0)
                    {
                    RB_PosX=0;
                    RB_Dir=RIGHT;
                    DosBeep(800,50);
                    }
                break;
            case RIGHT:
                RB_PosX++;
                if((RB_PosX+RB_SIZE)>=((RB_X-2)*RB_SIZE))
                    {
                    RB_PosX=(RB_X-3)*RB_SIZE;
                    RB_Dir=LEFT;
                    DosBeep(800,50);
                    }
                break;
            }
                                        /* Draw RollBall at new position */
            Draw_Bitmap(RB_RB,ROP_SRCCOPY,RB_PosX,RB_PosY);
                                        /* Now, test if the middle of RollBall is over any
                                           symbol. If a symbol is found, add points, deflect
                                           or end game */
                                        /* RB_Array is 1 based, because 0 indices are the
                                           playing ground borders */
            x=((RB_PosX)/RB_SIZE)+1;
            y=((RB_PosY)/RB_SIZE)+1;
                                        /* A Symbol if RB_SIZE*RB_SIZE in size, that means
                                           RollBall is exactly over a symbol, if the lower
                                           left edges of both symbols match. Then, and only
                                           then, we count points, deflect or loose */
            if((RB_PosX==(x-1)*RB_SIZE) && (RB_PosY==(y-1)*RB_SIZE))
                Symbol=RB_Array[x][y];
            else Symbol=RB_EMPTY;
            switch(Symbol)
            {
            case RB_LX:                 /* We got a \ deflector */
                {
                switch(RB_Dir)          /* \ deflects direction of RollBall */
                {
                case RIGHT:
                    RB_Dir=DOWN; break;
                case UP:
                    RB_Dir=LEFT; break;
                case LEFT:
                    RB_Dir=UP; break;
                case DOWN:
                    RB_Dir=RIGHT; break;
                }                       /* Remove deflector */
                RB_Array[x][y]=RB_EMPTY;
                break;
                }
            case RB_RX:                 /* We got a / deflector */
                {
                switch(RB_Dir)          /* / deflects direction of RollBall */
                {
                case RIGHT:
                    RB_Dir=UP; break;
                case UP:
                    RB_Dir=RIGHT; break;
                case LEFT:
                    RB_Dir=DOWN; break;
                case DOWN:
                    RB_Dir=LEFT; break;
                }                       /* Remove deflector */
                RB_Array[x][y]=RB_EMPTY;
                DosBeep(600,20);
                break;
                }
            case RB_BP:                 /* We got a point */
            case RB_GP:
            case RB_MP:
            case RB_VP:
                {                       /* Add the points for each symbol */
                RB_Point[0]+=RB_Point[Symbol];
                                        /* Remove the point */
                RB_Array[x][y]=RB_EMPTY;
                if (ulDelay)
                    ulDelay--;
                DosBeep(700,20);
                break;
                }
            case RB_HOLE:               /* We got a hole, sorry but RollBall will be killed.
                                           We disable RollBall from rolling, and send a 
                                           ID_STOPTHREAD message to our window, which
                                           informs the user about the points with a message
                                           box */
                {
                int     freq;
                for(freq=5000;freq>100;freq-=100) DosBeep(freq,5);
                runRB=FALSE;            /* Prevent RollBall from further rolling */
                WinPostMsg(hwndClient,WM_COMMAND,(MPARAM)ID_STOPTHREAD,(MPARAM)0);
                break;
                }
            }
                                        /* Randomly add and remove symbols on playing ground */
            if((rand()%500)<2)
                {
                Put_Random_Field();
                Clear_Random_Field();
                }
            }
        }
    }
DosOpen("TIMER0$",
        &hfile,
        &ulAction,
        0,
        0,
        OPEN_ACTION_OPEN_IF_EXISTS,
        OPEN_FLAGS_FAIL_ON_ERROR | OPEN_SHARE_DENYNONE | OPEN_ACCESS_READWRITE,
        NULL);   
ulDelay2=ulDelay/2;
DosDevIOCtl(hfile,
            HRT_IOCTL_CATEGORY,
            HRT_BLOCKUNTIL,
            &ulDelay2,
            ulSize2,
            &ulSize2,
            NULL,
            0,
            NULL);
DosClose(hfile);
}
WinReleasePS(hpsDT);                    /* Clean up */
WinDestroyMsgQueue(hmqDT);
WinTerminate(habDT);
DosExit(EXIT_THREAD,0UL);
}
Beispiel #18
0
BOOL ChangeWPS(PCHAR pszUserIni, PCHAR pszSystemIni)
   {
   PCHAR        pcEnv;
   PRFPROFILE   prfProfile;
   BOOL         bSuccess;

   if (*pszSystemIni == '\0')
      prfProfile.pszSysName = pShareInitOS2->pszRootSystemIni;
   else
      prfProfile.pszSysName = pszSystemIni;

   if (*prfProfile.pszSysName == '\0')
      prfProfile.pszSysName = (DosScanEnv (ENV_SYSTEM_INI, &pcEnv) ? "" : pcEnv);

   if (*pszUserIni == '\0')
      {
      prfProfile.pszUserName = pShareInitOS2->pszRootUserIni;
      pShareInitOS2->ulFlag  = pShareInitOS2->ulFlag_Root; // ulFlag f�r Rootdesktop
      }
   else
      prfProfile.pszUserName = pszUserIni;

   if (*prfProfile.pszUserName == '\0')
      prfProfile.pszUserName = (DosScanEnv (ENV_USER_INI, &pcEnv) ? "" : pcEnv);

   prfProfile.cchUserName = strlen(prfProfile.pszUserName);
   prfProfile.cchSysName  = strlen(prfProfile.pszSysName);

   if (ulOldFlag & CLOSEAPPL)
      WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "WORKAREA=YES");
   else
      WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "WORKAREA=NO");

   WinPostMsg(WinQueryWindow(HWND_DESKTOP, QW_BOTTOM), WM_CLOSE, 0, 0);
   DebugS (1, "HWND_DESKTOP closed");

   if( hevPrfResetLock )
      {
      DosWaitEventSem (hevPrfResetLock, SEM_INDEFINITE_WAIT);
      DosSleep(1000);
      DebugS (1, "hevPrfResetLock released");
      }
   else
      DosSleep(20000);

   bSuccess = PrfReset(hab, &prfProfile);
   DebugULd (1, "PrfReset", "return", bSuccess);

/*
 *  Beim Umschalten auf den Root, egal ob von Sammy oder von WPSamF ausgel�st,
 *  wird die Shell vom PrfReset nicht geschlossen.
 *  Solange die Ursache nicht bekannt ist, bleibt nichts anderes �brig,
 *  als an dieser Stelle symptomatisch vorzugehen und die Shell abzuschie�en.
 */
   if (*pszUserIni == '\0')
      {
      DosSuspendThread (tid1);
      DosKillProcess( DKP_PROCESSTREE, ulShellID );   // sog. Budnik'scher Arschtritt
      DebugS (1, "Shell killed");
      DosResumeThread (tid1);
      }

   if( !bSuccess )
      {
      WinSetObjectData(WinQueryObject("<WP_DESKTOP>"), "OPEN=ICON;WORKAREA=YES");
      DebugS (1, "Desktop set to <WP_DESKTOP>");
      intSammyRetCode = 250;
      WinPostQueueMsg (hmq, WM_QUIT, 0L, 0L);
      }
   else
      ulOldFlag = pShareInitOS2->ulFlag;

   return( bSuccess );
   }
Beispiel #19
0
ULONG ulExecProg (CHAR *szProgName)
   {
   ULONG        ulBootDrive;
   ULONG        ulAppType;
   CHAR         szCmdName[CCHMAXPATH];
   CHAR         szLine[CCHMAXPATH];
   PSZ          pszScanEnv;
   RESULTCODES  rcTermination;
   APIRET       rcFailure = 0;
   PCHAR        pszEnvironment;

/*
 *  Diese Routine versucht eine Shell zu starten.
 */

   pszEnvironment = MakeEnv (pShareInitOS2->pszEnvironment);

   if ( !(rcFailure = ScanEnv(ENV_SAMWORKPLACE, &pszScanEnv, pszEnvironment)) )
      {
      rcFailure = DosQueryAppType(pszScanEnv, &ulAppType);

      if ( !rcFailure )
         if ( ( (ulAppType & 7) == FAPPTYP_NOTSPEC) ||
              ( (ulAppType & 7) == FAPPTYP_WINDOWAPI) )
            rcFailure = DosExecPgm (szLine,           /* Object name buffer */
                                 sizeof(szLine),      /* Length of object name buffer */
                                 EXEC_ASYNCRESULT,    /* Execution flags */
                                 "",                  /* Argument string */
                                 pszEnvironment,       /* Environment */
                                 &rcTermination,      /* Termination codes */
                                 pszScanEnv);         /* Program file name */
         else
            rcFailure = 1;
      }

   if (rcFailure)
      {
      WinAlarm (HWND_DESKTOP, WA_ERROR);
      DebugS (1, "DosExecPgm <1> failed");
      }

   if (rcFailure)
      {
      rcFailure = DosExecPgm (szLine,              /* Object name buffer */
                              sizeof(szLine),      /* Length of object name buffer */
                              EXEC_ASYNCRESULT,    /* Execution flags */
                              "",                  /* Argument string */
                              pszEnvironment,       /* Environment */
                              &rcTermination,      /* Termination codes */
                              szProgName);         /* Program file name */
      }

   if (rcFailure)
      {
      if (!(rcFailure = DosScanEnv (ENV_SAMWORKPLACE, &pszScanEnv)))
         rcFailure = DosExecPgm (szLine,        /* Object name buffer */
                           sizeof(szLine),      /* Length of object name buffer */
                           EXEC_ASYNCRESULT,    /* Execution flags */
                           "",                  /* Argument string */
                           pszEnvironment,       /* Environment */
                           &rcTermination,      /* Termination codes */
                           pszScanEnv);         /* Program file name */
      }

   if (rcFailure)
      {
      DebugS (1, "DosExecPgm <2> failed");
      DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ULONG));

      memset (szCmdName, '\0', sizeof(szCmdName));
      szCmdName[0] = (CHAR) (ulBootDrive - 1) + 'A';
      strcpy (szCmdName+1, ":\\OS2\\PMSHELL.EXE");

      rcFailure = DosExecPgm (szLine,           /* Object name buffer */
                           sizeof(szLine),      /* Length of object name buffer */
                           EXEC_ASYNCRESULT,    /* Execution flags */
                           "",                  /* Argument string */
                           pszEnvironment,       /* Environment */
                           &rcTermination,      /* Termination codes */
                           szCmdName);          /* Program file name */
      }

/* Falls Shell nicht gestartet werden konnte, wird cmd.exe aufgerufen */

   if (rcFailure)
      {
      DebugS (1, "DosExecPgm <3> failed");
      if (!(rcFailure = DosScanEnv ("COMSPEC", &pszScanEnv)))
         rcFailure = DosExecPgm (szLine,        /* Object name buffer */
                           sizeof(szLine),      /* Length of object name buffer */
                           EXEC_ASYNCRESULT,    /* Execution flags */
                           "/K",                /* Argument string */
                           pszEnvironment,       /* Environment */
                           &rcTermination,      /* Termination codes */
                           pszScanEnv);         /* Program file name */
      }

   if (rcFailure)
      {
      DebugS (1, "DosExecPgm <4> failed");
      DosQuerySysInfo (QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, &ulBootDrive, sizeof (ULONG));

      memset (szCmdName, '\0', sizeof(szCmdName));
      szCmdName[0] = (CHAR) (ulBootDrive - 1) + 'A';
      strcpy (szCmdName+1, ":\\OS2\\CMD.EXE");

      rcFailure = DosExecPgm (szLine,        /* Object name buffer */
                        sizeof(szLine),      /* Length of object name buffer */
                        EXEC_ASYNCRESULT,    /* Execution flags */
                        "/K",                /* Argument string */
                        pszEnvironment,       /* Environment */
                        &rcTermination,      /* Termination codes */
                        szCmdName);          /* Program file name */
      }

   DosFreeMem(pszEnvironment);

   if (rcFailure)
      {
      intSammyRetCode = rcFailure;
      WinPostQueueMsg (hmq, WM_CLOSE, 0L, 0L);
      DebugS (1, "DosExecPgm <5> failed");
      }

   return (rcFailure ? 0 : rcTermination.codeTerminate);
   }
// Frame_window - окно рамки, Target и Buttons_to_detect - какое свойство надо узнать.
// Update_frame_if_required - рамку можно обновить если это требуется.
VOID Diver_QueryWindowProperty( HWND Frame_window, ULONG Target, LONG Buttons_to_detect = ALL_ACTIONS, BYTE Update_frame_if_required = 0 )
{
 // Узнаем расположение окна и его состояние.
 SWP Window_state = {0}; WinQueryWindowPos( Frame_window, &Window_state );

 // Если окно уменьшено в значок или скрыто - возврат.
 if( Window_state.fl & SWP_MINIMIZE || Window_state.fl & SWP_HIDE ) return;

 // Узнаем значок окна.
 if( Target & WT_SYSMENU )
  {
   // Узнаем значок окна.
   HPOINTER Icon = Diver_QueryWindowIcon( Frame_window );

   // Если он есть:
   if( Icon != NULLHANDLE )
    {
     // Если значок изменился - рамка должна быть перерисована.
     HPOINTER Previous_icon = NULLHANDLE; FindProperty( Frame_window, PRP_ICON, &Previous_icon );

     if( Icon != Previous_icon )
      {
       // Устанавливаем свойство.
       SetProperty( Frame_window, PRP_ICON, &Icon );

       // Посылаем сообщение в поток рисования.
       WinPostQueueMsg( Enhancer.Modules.Painter->Message_queue, SM_DRAW_FRAME, (MPARAM) Frame_window, (MPARAM) WT_SYSMENU );
      }
    }
  }

 // Узнаем ширину рамки окна.
 if( Target & WT_SYSMENU )
  {
   // Отправляем сообщение в окно.
   Diver.RTSettings.FB_size.x = 0; Diver.RTSettings.FB_size.y = 0;
   WinSendMsg( Frame_window, WM_QUERYBORDERSIZE, (MPARAM) &Diver.RTSettings.FB_size, 0 );

   // Шириной рамки будем считать наименьшее полученное значение.
   INT Width = min( Diver.RTSettings.FB_size.x, Diver.RTSettings.FB_size.y );

   // Если оно было получено:
   if( Width != 0 )
    {
     // Если ширина изменилась - рамка должна быть перерисована.
     INT Previous_width = 0; FindProperty( Frame_window, PRP_BORDER, &Previous_width );

     if( Width != Previous_width )
      {
       // Устанавливаем свойство.
       SetProperty( Frame_window, PRP_BORDER, &Width );

       // Узнаем значение по умолчанию.
       INT System_value = FrameWidth( Frame_window );

       // Если это другое значение - посылаем сообщение в поток рисования.
       if( Width != System_value )
        {
         ULONG Update_all = WT_BORDER | WT_SYSMENU | WT_TITLEBAR | WT_MINMAX | WT_MENU;
         WinPostQueueMsg( Enhancer.Modules.Painter->Message_queue, SM_DRAW_FRAME, (MPARAM) Frame_window, (MPARAM) Update_all );
        }
      }
    }
  }

 // Узнаем заголовок окна.
 if( Target & WT_TITLEBAR )
  {
   // Узнаем заголовок окна.
   HWND TitleBar_window = WinWindowFromID( Frame_window, FID_TITLEBAR );
   CHAR Title[ SIZE_OF_TITLE ] = ""; QueryWindowTitle( Frame_window, TitleBar_window, Title, Update_frame_if_required );

   // Если заголовок определен:
   if( Title[ 0 ] != 0 )
    {
     // Если заголовок изменился - рамка должна быть перерисована.
     CHAR Previous_title[ SIZE_OF_TITLE ] = ""; FindProperty( Frame_window, PRP_TITLE, Previous_title );

     if( !strc( Title, Previous_title ) )
      {
       // Устанавливаем свойство.
       SetProperty( Frame_window, PRP_TITLE, Title );

       // Посылаем сообщение в поток рисования.
       WinPostQueueMsg( Enhancer.Modules.Painter->Message_queue, SM_DRAW_FRAME, (MPARAM) Frame_window, (MPARAM) WT_TITLEBAR );
      }
    }
  }

 // Узнаем состояние кнопок в правом верхнем углу окна.
 if( Target & WT_MINMAX )
  {
   // Узнаем, есть ли это свойство в списке.
   BYTE Actions_are_detected = 0; FindProperty( Frame_window, PRP_ACTIONS, &Actions_are_detected );

   // Если его нет - узнаем состояние кнопок по умолчанию.
   if( !Actions_are_detected )
    {
     // Узнаем состояние кнопок по умолчанию.
     LONG Buttons_state = Diver_GetPreDefinedButtonsState( Frame_window );

     // Запоминаем, что состояние кнопок определено.
     BYTE Detected = 1; SetProperty( Frame_window, PRP_ACTIONS, &Detected );

     // Если оно задано - рамка должна быть перерисована.
     if( Buttons_state != NO_ACTION )
      {
       // Устанавливаем свойство.
       SetProperty( Frame_window, PRP_BUTTONS, &Buttons_state );

       // Посылаем сообщение в поток рисования.
       WinPostQueueMsg( Enhancer.Modules.Painter->Message_queue, SM_DRAW_FRAME, (MPARAM) Frame_window, (MPARAM) WT_BORDER );
      }
    }

   // Узнаем состояние кнопок в окне.
   LONG Buttons_state = QueryButtonsState( Frame_window, Buttons_to_detect, 1 );

   // Если состояние кнопок изменилось - рамка должна быть перерисована.
   LONG Previous_state = NO_ACTION; FindProperty( Frame_window, PRP_BUTTONS, &Previous_state );

   if( Buttons_state != Previous_state )
    {
     // Устанавливаем свойство.
     SetProperty( Frame_window, PRP_BUTTONS, &Buttons_state );

     // Посылаем сообщение в поток рисования.
     WinPostQueueMsg( Enhancer.Modules.Painter->Message_queue, SM_DRAW_FRAME, (MPARAM) Frame_window, (MPARAM) WT_BORDER );
    }
  }

 // Возврат.
 return;
}
Beispiel #21
0
VOID gropFree(PGROPDATA pGrop)
{
  ULONG      ulRC;
  HMQ        hmq;
  TID        tid;

  ulRC = DosRequestMutexSem( pGrop->hmtxData, 4000 );
  if ( ulRC != NO_ERROR )
    debug( "DosRequestMutexSem(), rc = %u", ulRC );

  hmq = pGrop->hmq;
  tid = pGrop->tid;
  // Tune off all callback functions.
  memset( &pGrop->stCallback, 0, sizeof(GROPCALLBACK) );
  DosReleaseMutexSem( pGrop->hmtxData );

  if ( ( hmq == NULLHANDLE ) || !WinPostQueueMsg( hmq, WM_QUIT, 0, 0 ) )
  {
    debug( "Hm... have not a thread?..." );
    if ( pGrop->fFullscreen )
      _setMode( pGrop, pGrop->ulModeIdx, FALSE );

    if ( tid != ((TID)(-1)) )
    {
      debug( "WTF?! %p %d", pGrop, tid );
      DosKillThread( tid );
    }
  }
  else if ( DosWaitThread( &tid, DCWW_NOWAIT ) != NO_ERROR )
  {
    debug( "Wait thread semaphore" );
    ulRC = DosWaitEventSem( pGrop->hevReady, 4000 );
    if ( ulRC != NO_ERROR )
    {
      PVIDEOMODE pMode = &pGrop->stModes.pList[pGrop->stModes.ulDesktopMode];

      debug( "DosWaitEventSem(), rc = %u. Kill thread...", ulRC );
      DosKillThread( tid );

      if ( pGrop->hwndDT != NULLHANDLE )
      {
        debug( "Return to the desktop..." );
        pGrop->pVideoSys->fnSetMode( pGrop->pVSData, pMode, FALSE,
                                     pGrop->hwndDT, pGrop->hdcDT );
      }
    }
    else
    {
      debug( "Wait thread" );
      DosWaitThread( &tid, DCWW_WAIT );
    }
  }
  else
    debug( "Thread already terminated." );

  // Remove GROP object from the list.
  ulRC = DosRequestMutexSem( hmtxGropList, SEM_INDEFINITE_WAIT );
  if ( ulRC != NO_ERROR )
    debug( "DosRequestMutexSem(), rc = %u", ulRC );
  lnkseqRemove( &lsGropList, pGrop );
  DosReleaseMutexSem( hmtxGropList );

  DosCloseEventSem( pGrop->hevReady );
  debugFree( pGrop );
  debug( "Success." );
}
Beispiel #22
0
void OS2Loop::exit()
{
    WinPostQueueMsg( HMQ_CURRENT, WM_QUIT, 0, 0 );
}
// Frame_window - окно рамки.
HPOINTER Diver_QueryWindowIcon( HWND Frame_window )
{
 // Для некоторых окон есть значки по умолчанию, но устанавливать их нельзя.
 if( IsEPMEditorWindow( Frame_window ) || WindowIsCreatedBy( APP_EPM, Frame_window ) )
  {
   if( Diver.RTSettings.EPM_icon == NULLHANDLE )
    {
     ULONG Boot_drive = 0;
     DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, (PULONG) &Boot_drive, sizeof( Boot_drive ) );

     if( Boot_drive )
      {
       CHAR Path[ SIZE_OF_PATH ] = "*:";
       Path[ 0 ] = (CHAR) Boot_drive + 64; strcat( Path, "\\OS2\\Apps\\Epm.exe" );

       if( FileExists( Path ) ) Diver.RTSettings.EPM_icon = WinLoadFileIcon( Path, 0 );
      }
    }

   if( Diver.RTSettings.EPM_icon != NULLHANDLE ) return Diver.RTSettings.EPM_icon;
   else return Resources.Default_icons[ ICON_VIEWDOC ];
  }

 // Для некоторых окон значки по умолчанию можно установить раз и навсегда, отправив сообщение в окно.
 HPOINTER Icon = NULLHANDLE;

 if( Icon == NULLHANDLE )
  {
   if( IsWinListWindow( Frame_window ) ) Icon = Resources.Default_icons[ ICON_WINLIST ];
  }

 if( Icon == NULLHANDLE )
  {
   if( WindowIsCreatedBy( APP_VIEWDOC, Frame_window ) ) Icon = Resources.Default_icons[ ICON_VIEWDOC ];
  }

 if( Icon == NULLHANDLE )
  {
   if( WindowIsCreatedBy( APP_PMCHKDSK, Frame_window ) )
    {
     if( Diver.RTSettings.HDD_icon == NULLHANDLE )
      {
       ULONG Boot_drive = 0;
       DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE, (PULONG) &Boot_drive, sizeof( Boot_drive ) );

       if( Boot_drive )
        {
         CHAR Path[ SIZE_OF_PATH ] = "*:";
         Path[ 0 ] = (CHAR) Boot_drive + 64; strcat( Path, "\\eCS\\Bin\\PMFormat.exe" );
         if( FileExists( Path ) ) Diver.RTSettings.HDD_icon = WinLoadFileIcon( Path, 0 );
        }
      }

     if( Diver.RTSettings.HDD_icon == NULLHANDLE )
      {
       CHAR Path[ SIZE_OF_PATH ] = "";
       HOBJECT WPDrives_object = QueryWPSObject( "<WP_DRIVES>" );
       if( WPDrives_object != NULLHANDLE ) WinQueryObjectPath( WPDrives_object, Path, SIZE_OF_PATH );
       if( Path[ 0 ] != 0 ) Diver.RTSettings.HDD_icon = WinLoadFileIcon( Path, 0 );
      }

     if( Diver.RTSettings.HDD_icon != NULLHANDLE ) Icon = Diver.RTSettings.HDD_icon;
    }
  }

 if( Icon == NULLHANDLE )
  {
   if( WindowIsCreatedBy( APP_APPLETVIEWER, Frame_window ) )
    {
     HWND Related_window = FindRelatedFrameWindow( Frame_window, &IsHotJavaBrowserWindow );

     if( Related_window != NULLHANDLE )
      {
       Icon = (HPOINTER) WinSendMsg( Related_window, WM_QUERYICON, 0, 0 );
      }
    }
  }

 // Если значок был выбран - ставим и возвращаем его.
 if( Icon != NULLHANDLE )
  {
   if( DrawSystemMenusSettingIsON() )
    {
     WinPostQueueMsg( Enhancer.Modules.Changer->Message_queue, SM_CHANGE_ICON, (MPARAM) Frame_window, (MPARAM) Icon );
    }

   return Icon;
  }

 // Узнаем значок окна.
 Icon = (HPOINTER) WinSendMsg( Frame_window, WM_QUERYICON, 0, 0 );

 // Если это пустой значок - ставим изображение по умолчанию.
 HWND Desktop = QueryDesktopWindow();

 if( Icon == WinQuerySysPointer( Desktop, SPTR_APPICON, 0 ) )
  {
   Icon = WinQuerySysPointer( Desktop, SPTR_PROGRAM, 0 );

   if( DrawSystemMenusSettingIsON() )
    {
     WinPostQueueMsg( Enhancer.Modules.Changer->Message_queue, SM_CHANGE_ICON, (MPARAM) Frame_window, (MPARAM) Icon );
    }

   return Icon;
  }

 // Если значок неизвестен - возвращаем значок владельца, главного окна, или значок по умолчанию.
 // Менять значок во всех случаях нельзя - может возникнуть постоянное рисование, которое выглядит как "мигание" рамки.
 if( Icon == NULLHANDLE )
  {
   // Узнаем окно рабочего стола.
   HWND Desktop = QueryDesktopWindow();

   // Просматриваем всех владельцев.
   HWND Owner_window = WinQueryWindow( Frame_window, QW_FRAMEOWNER );

   while( Owner_window != Desktop && Owner_window != NULLHANDLE )
    {
     // Если владелец - окно рамки:
     if( IsFrameWindow( Owner_window ) )
      {
       // Узнаем его значок.
       Icon = (HPOINTER) WinSendMsg( Owner_window, WM_QUERYICON, 0, 0 );

       // Если он есть - возвращаем его.
       if( Icon != NULLHANDLE ) return Icon;
      }

     // Узнаем следующего владельца.
     Owner_window = WinQueryWindow( Owner_window, QW_FRAMEOWNER );
    }

   // Узнаем главное окно приложения.
   HWND Main_window = QueryMainWindow( Frame_window );

   // Если это другое окно:
   if( Main_window != Frame_window )
    {
     // Узнаем его значок.
     Icon = (HPOINTER) WinSendMsg( Main_window, WM_QUERYICON, 0, 0 );

     // Если он есть - возвращаем его.
     if( Icon != NULLHANDLE ) return Icon;
    }

   // Узнаем очередь сообщений окна.
   HMQ Message_queue = WinQueryWindowULong( Frame_window, QWL_HMQ );

   // Узнаем окно оболочки.
   HWND Shell_window = GetDetectedShellWindow();

   if( Shell_window != NULLHANDLE )
    {
     // Узнаем очередь сообщений для окна оболочки.
     HMQ Shell_queue = WinQueryWindowULong( Shell_window, QWL_HMQ );

     // Если очереди совпадают - возвращаем его значок.
     if( Shell_queue == Message_queue ) return (HPOINTER) WinSendMsg( Shell_window, WM_QUERYICON, 0, 0 );

     // Если еще как-нибудь можно установить, что окно создано оболочкой - возвращаем значок окна оболочки.
     if( IsWorkplaceShellWindow( Frame_window ) ) return (HPOINTER) WinSendMsg( Shell_window, WM_QUERYICON, 0, 0 );
    }

   {
    // Перебираем окна в окне рабочего стола.
    HENUM Enumeration = WinBeginEnumWindows( Desktop ); HWND Window = NULLHANDLE;
    while( ( Window = WinGetNextWindow( Enumeration ) ) != NULLHANDLE )
     {
      // Если это то же самое окно - продолжаем перебор окон.
      if( Window == Frame_window ) continue;

      // Узнаем расположение окна и его состояние.
      SWP Window_state = {0}; WinQueryWindowPos( Window, &Window_state );

      // Если окно не скрыто и не уменьшено в значок:
      if( !( Window_state.fl & SWP_HIDE ) ) if( !( Window_state.fl & SWP_MINIMIZE ) )
       {
        // Если в это окно нельзя переключиться - продолжаем перебор окон.
        if( !PermissionForSwitching( Window ) ) continue;
       }

      // Узнаем очередь сообщений окна.
      HMQ Window_queue = WinQueryWindowULong( Window, QWL_HMQ );

      // Если очереди совпадают - узнаем его значок.
      if( Window_queue == Message_queue )
       {
        // Узнаем значок окна.
        Icon = (HPOINTER) WinSendMsg( Window, WM_QUERYICON, 0, 0 );

        // Если он есть - возвращаем его.
        if( Icon != NULLHANDLE )
         {
          // Завершаем перебор окон.
          WinEndEnumWindows( Enumeration );

          // Возвращаем значок.
          return Icon;
         }
       }
     }
    WinEndEnumWindows( Enumeration );
   }

   // Узнаем путь к приложению, создавшему окно.
   CHAR Path[ SIZE_OF_PATH ] = ""; GetDetectedExePath( Frame_window, Path );

   // Если его удалось определить:
   if( Path[ 0 ] != 0 )
    {
     // Узнаем имя приложения, создавшего окно.
     CHAR Name[ SIZE_OF_PATH ] = ""; GetDetectedExeName( Frame_window, Name );

     // Составляем полный путь.
     strcat( Path, "\\" ); strcat( Path, Name );

     // Загружаем значок для файла приложения.
     Icon = WinLoadFileIcon( Path, 0 );

     // Загрузка длится долго, поэтому в этом случае надо заменить значок окна. При
     // повторной загрузке возможна утечка памяти, так что лучше сделать это немедленно,
     // не посылая сообщений в поток Changer.
     WinSendMsg( Frame_window, WM_SETICON, (MPARAM) Icon, 0 );

     // Запоминаем, что значок был загружен с диска.
     BYTE Icon_was_loaded = 1; SetProperty( Frame_window, PRP_ICON_WAS_LOADED, &Icon_was_loaded );

     // Возвращаем значок.
     return Icon;
    }

   // Для окон постоянного размера выбираем простой значок.
   if( WindowIsDialog( Frame_window ) )
    {
     return Resources.Default_icons[ ICON_LEAF ];
    }
   // Для остальных окон - он зависит от того, можно ли переключиться в окно.
   else
    {
     HSWITCH Switch_handle = WinQuerySwitchHandle( Frame_window, NULLHANDLE );

     if( Switch_handle != NULLHANDLE ) return Resources.Default_icons[ ICON_LEAVES ];
     else return Resources.Default_icons[ ICON_LEAF ];
    }

   // И наконец, значок мог быть задан в свойствах раньше.
   FindProperty( Frame_window, PRP_ICON, &Icon );
  }

 // Возврат.
 return Icon;
}
// Все переменные - внешние.
VOID RoomsKbdInputHook( HAB Application, PQMSG Message, PBYTE Discarding )
{
 // Если надо добавить комнаты к рабочему столу:
 if( Rooms.Settings.Create_Rooms )
  {
   // Переходим в другую комнату при нажатии на цифровые клавиши. Посылаем сообщение в поток и сбрасываем пришедшее сообщение.
   if( Rooms.Settings.Switch_by_keyboard )
    if( Message->msg == WM_CHAR )
     {
      // Смотрим, какая клавиша нажата.
      BYTE Scan_code = CHAR4FROMMP( Message->mp1 );
      SHORT State = SHORT1FROMMP( Message->mp1 );

      // Если идет нажатие клавиши:
      if( !( State & KC_KEYUP ) ) if( !( State & KC_PREVDOWN ) )
       {
        // Узнаем, в какую комнату надо перейти.
        INT Room = 0;

        // Должна быть нажата клавиша Shift и цифровая клавиша.
        if( State & KC_SHIFT ) if( ShiftIsPressed() )
         {
          if( Scan_code == SC_NUM_5 ) Room = SHELL_ROOM;
          if( Scan_code == SC_NUM_8 ) Room = NORTHERN_ROOM;
          if( Scan_code == SC_NUM_4 ) Room = WESTERN_ROOM;
          if( Scan_code == SC_NUM_6 ) Room = EASTERN_ROOM;
          if( Scan_code == SC_NUM_2 ) Room = SOUTHERN_ROOM;

          if( Scan_code == SC_NUM_7 || Scan_code == SC_NUM_9 ||
              Scan_code == SC_NUM_1 || Scan_code == SC_NUM_3 ) Room = CURRENT_ROOM;
         }

        // Если вызвана заставка - действие выполнять не надо.
        if( Room ) if( SystemIsLocked() ) { Room = 0; *Discarding = 1; }

        // Если надо переключиться в другую комнату:
        if( Room )
         {
          // Посылаем сообщение в поток.
          if( Room != CURRENT_ROOM ) WinPostQueueMsg( Enhancer.Modules.Rooms->Message_queue, SM_GO_TO_ROOM, (MPARAM) Room, 0 );

          // Сообщение должно быть сброшено.
          *Discarding = 1;
         }
       }
     }

   // Добиваемся правильной работы потоков после перехода между комнатами.
   if( Rooms.Settings.Synchronize_arranger_and_rooms )
    {
     // Если была нажата любая клавиша - считаем, что смена комнат завершена.
     if( Message->msg == WM_CHAR )
      {
       // Смотрим, какая клавиша нажата.
       BYTE Scan_code = CHAR4FROMMP( Message->mp1 );
       SHORT State = SHORT1FROMMP( Message->mp1 );

       // Если идет нажатие клавиши:
       if( !( State & KC_KEYUP ) ) if( !( State & KC_PREVDOWN ) )
        {
         // Если эта клавиша не используется дл переключения между комнатами - смена комнат завершена.
         if( Scan_code < SC_NUM_FIRST || Scan_code > SC_NUM_LAST )
          Rooms.Settings.Synchronize_arranger_and_rooms = 0;
        }
      }
    }
  }

 // Возврат.
 return;
}
// Все переменные - внешние.
VOID RoomsInputHook( HAB Application, PQMSG Message, PBYTE Discarding )
{
 // Если надо добавить комнаты к рабочему столу:
 if( Rooms.Settings.Create_Rooms )
  {
   // Переходим в другую комнату при получении сообщения WM_MARK.
   if( Rooms.Settings.Switch_by_WarpCenter )
    if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_GO_TO_ROOM )
     {
      // Узнаем, в какую комнату надо перейти.
      LONG Scan_code = (LONG) Message->mp2; INT Room = 0;

      if( Scan_code == SC_NUM_5 ) Room = SHELL_ROOM;
      if( Scan_code == SC_NUM_8 ) Room = NORTHERN_ROOM;
      if( Scan_code == SC_NUM_4 ) Room = WESTERN_ROOM;
      if( Scan_code == SC_NUM_6 ) Room = EASTERN_ROOM;
      if( Scan_code == SC_NUM_2 ) Room = SOUTHERN_ROOM;

      if( Scan_code == SC_NUM_7 || Scan_code == SC_NUM_9 ||
          Scan_code == SC_NUM_1 || Scan_code == SC_NUM_3 ) Room = CURRENT_ROOM;

      // Если вызвана заставка - действие выполнять не надо.
      if( Room )
       if( SystemIsLocked() ) { Room = 0; *Discarding = 1; }

      // Если надо переключиться в другую комнату:
      if( Room )
       {
        // Посылаем сообщение в поток.
        if( Room != CURRENT_ROOM ) WinPostQueueMsg( Enhancer.Modules.Rooms->Message_queue, SM_GO_TO_ROOM, (MPARAM) Room, 0 );

        // Сообщение должно быть сброшено.
        *Discarding = 1;
       }
     }

   // Закрашиваем окно рабочего стола.
   if( Rooms.Settings.Draw_wallpaper )
    {
     // Если окно должно быть перерисовано и это рабочий стол:
     if( Message->msg == WM_PAINT ) if( Message->hwnd == QueryDesktopWindow() )
      {
       // Посылаем в очередь окна сообщение WM_MARK. Когда оно будет получено, окно можно будет закрасить.
       HMQ Message_queue = WinQueryWindowULong( Message->hwnd, QWL_HMQ );
       WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_FILL_DESKTOP, (MPARAM) Message->hwnd );
      }

     // Обрабатываем сообщение WM_MARK.
     if( Message->hwnd == NULLHANDLE ) if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_FILL_DESKTOP )
      {
       HWND Window = (HWND) Message->mp2;
       if( Window == QueryDesktopWindow() )
        {
         // Посылаем сообщение в поток.
         WinPostQueueMsg( Enhancer.Modules.Rooms->Message_queue, SM_FILL_DESKTOP, (MPARAM) Window, 0 );
        }
      }
    }

   // Вызываем LaunchPad или список окон при нажатии кнопок мыши в окне рабочего стола.
   BYTE Show_LaunchPad = 0; BYTE Show_Window_list = 0; BYTE Hide_Window_list = 0;

   // Если левая кнопка мыши нажата дважды - вызываем LaunchPad.
   if( Message->msg == WM_BUTTON1DBLCLK )
    if( Message->hwnd == QueryDesktopWindow() ) Show_LaunchPad = 1;

   // Если она нажата один раз:
   if( Message->msg == WM_BUTTON1DOWN )
    {
     // Узнаем окно рабочего стола.
     HWND Desktop = QueryDesktopWindow();

     // Если мышь нажата в окне рабочего стола - проверяем состояние других кнопок мыши.
     if( Message->hwnd == Desktop )
      {
       if( MouseButtonIsPressed( 2 ) || MouseButtonIsPressed( 3 ) )
        Show_Window_list = 1;
       else
        Hide_Window_list= 1;
      }
    }

   // Если нажата правая или средняя кнопка:
   if( Message->msg == WM_BUTTON2DOWN || Message->msg == WM_BUTTON3DOWN )
    {
     // Узнаем окно рабочего стола.
     HWND Desktop = QueryDesktopWindow();

     // Если мышь нажата в окне рабочего стола - проверяем состояние левой кнопки мыши.
     if( Message->hwnd == Desktop )
      {
       if( MouseButtonIsPressed( 1 ) )
        Show_Window_list = 1;
       else
        Hide_Window_list = 1;
      }
    }

   // Если надо вызвать LaunchPad или список окон - посылаем сообщение в поток.
   if( Show_LaunchPad ) WinPostQueueMsg( Enhancer.Modules.Launcher->Message_queue, SM_SHOW_LAUNCHPAD, 0, 0 );
   if( Show_Window_list ) WinPostQueueMsg( Enhancer.Modules.Launcher->Message_queue, SM_SHOW_WINDOW_LIST, (MPARAM) 1, 0 );
   if( Hide_Window_list )
    {
     WinPostQueueMsg( Enhancer.Modules.Launcher->Message_queue, SM_HIDE_WINDOW_LIST, 0, 0 );
     WinPostQueueMsg( Enhancer.Modules.Launcher->Message_queue, SM_HIDE_WARPCENTER, 0, 0 );
    }

   // Если используется оболочка WPS:
   if( ShellIsWPS() )
    {
     // Проверяем окно WPS, которое становится выбранным, чтобы скрыть окно оболочки.
     // Это сообщение посылается в окно в SendMsgHook() при обработке сообщения WM_ACTIVATE.
     if( GetCurrentOrNextRoom() != SHELL_ROOM )
      if( Message->hwnd == NULLHANDLE ) if( Message->msg == WM_MARK ) if( Message->mp1 == (MPARAM) MRK_CHECK_WINDOW )
       {
        // Посылаем сообщение в поток.
        HWND Window = (HWND) Message->mp2;
        WinPostQueueMsg( Enhancer.Modules.Rooms->Message_queue, SM_CHECK_WINDOW, (MPARAM) Window, 0 );
       }
    }

   // Добиваемся правильной работы потоков после перехода между комнатами.
   if( Rooms.Settings.Synchronize_arranger_and_rooms )
    {
     // Если была нажата кнопка мыши - считаем, что смена комнат завершена.
     if( Message->msg == WM_BUTTON1DOWN || Message->msg == WM_BUTTON2DOWN || Message->msg == WM_BUTTON3DOWN )
      if( Message->hwnd != CurtainWindow() )
       if( MouseIsBusy() )
        Rooms.Settings.Synchronize_arranger_and_rooms = 0;
    }
  }

 // Возврат.
 return;
}
// Input_window - окно, Command - какие буквы надо вставить.
VOID Clipper_PasteFireFoxCharacters( HWND Input_window, ULONG Command )
{
 // Запоминаем содержимое Clipboard. Для работы с FireFox требуется не только
 // обыкновеннай текст, но и текст в кодировке UCS2, которую понимает Mozilla.
 if( Clipper.RTSettings.Clipboard_data_Text != NULL ) { DosFreeMem( Clipper.RTSettings.Clipboard_data_Text ); Clipper.RTSettings.Clipboard_data_Text = NULL; }
 if( Clipper.RTSettings.Clipboard_data_UCS2 != NULL ) { DosFreeMem( Clipper.RTSettings.Clipboard_data_UCS2 ); Clipper.RTSettings.Clipboard_data_UCS2 = NULL; }

 {
  Clipper.RTSettings.Clipboard_data_Text_length = 0;
  Clipper.RTSettings.Clipboard_data_UCS2_length = 0;

  INT Max_length = 16384; PBYTE Text = NULL;
  if( DosAllocMem( (PPVOID) &Text, Max_length, PAG_ALLOCATE ) != NO_ERROR ) return;

  GetStringFromClipboard( Enhancer.Application, Text, Max_length );
  INT Real_length = strlen( Text ) + 1;

  DosFreeMem( Text ); Text = NULL;

  Clipper.RTSettings.Clipboard_data_Text_length = Real_length;
  Clipper.RTSettings.Clipboard_data_UCS2_length = Real_length * 2;
 }

 if( DosAllocMem( (PPVOID) &Clipper.RTSettings.Clipboard_data_Text, Clipper.RTSettings.Clipboard_data_Text_length, PAG_ALLOCATE ) != NO_ERROR ) return;
 if( DosAllocMem( (PPVOID) &Clipper.RTSettings.Clipboard_data_UCS2, Clipper.RTSettings.Clipboard_data_UCS2_length, PAG_ALLOCATE ) != NO_ERROR ) return;

 bzero( Clipper.RTSettings.Clipboard_data_Text, Clipper.RTSettings.Clipboard_data_Text_length );
 bzero( Clipper.RTSettings.Clipboard_data_UCS2, Clipper.RTSettings.Clipboard_data_UCS2_length );

 CHAR Mozilla_internal_format[] = "text/unicode";

 GetStringFromClipboard( Enhancer.Application,
                         Clipper.RTSettings.Clipboard_data_Text,
                         Clipper.RTSettings.Clipboard_data_Text_length,
                         Clipper.RTSettings.Clipboard_data_UCS2,
                         Clipper.RTSettings.Clipboard_data_UCS2_length,
                         Mozilla_internal_format );

 // Задаем новую строку в обычном виде и в виде UCS2-строки.
 BYTE Common_string[ 3 ] = { 0x00, 0x00, 0x00 };
 BYTE UCS2LittleEndian_string[ 6 ] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 LONG UCS2LittleEndian_string_length = 0;

 #include "Modules\\Clipper\\Clipper_ffx.cpp"

 if( Command == SM_FFX_PASTE_DASH )
  {
   Common_string[ 0 ] = '-';
   Common_string[ 1 ] = 0x00;

   UCS2LittleEndian_string[ 0 ] = Dash_in_Unicode[ 1 ];
   UCS2LittleEndian_string[ 1 ] = Dash_in_Unicode[ 0 ];
   UCS2LittleEndian_string[ 2 ] = 0x00;
   UCS2LittleEndian_string[ 3 ] = 0x00;

   UCS2LittleEndian_string_length = 4;
  }

 if( Command == SM_FFX_PASTE_QUOTES_1 )
  {
   Common_string[ 0 ] = '"';
   Common_string[ 1 ] = '"';
   Common_string[ 2 ] = 0x00;

   UCS2LittleEndian_string[ 0 ] = Primary_quote_1_in_Unicode[ 1 ];
   UCS2LittleEndian_string[ 1 ] = Primary_quote_1_in_Unicode[ 0 ];
   UCS2LittleEndian_string[ 2 ] = Primary_quote_2_in_Unicode[ 1 ];
   UCS2LittleEndian_string[ 3 ] = Primary_quote_2_in_Unicode[ 0 ];
   UCS2LittleEndian_string[ 4 ] = 0x00;
   UCS2LittleEndian_string[ 5 ] = 0x00;

   UCS2LittleEndian_string_length = 6;
  }

 if( Command == SM_FFX_PASTE_QUOTES_2 )
  {
   Common_string[ 0 ] = '"';
   Common_string[ 1 ] = '"';
   Common_string[ 2 ] = 0x00;

   UCS2LittleEndian_string[ 0 ] = Secondary_quote_1_in_Unicode[ 1 ];
   UCS2LittleEndian_string[ 1 ] = Secondary_quote_1_in_Unicode[ 0 ];
   UCS2LittleEndian_string[ 2 ] = Secondary_quote_2_in_Unicode[ 1 ];
   UCS2LittleEndian_string[ 3 ] = Secondary_quote_2_in_Unicode[ 0 ];
   UCS2LittleEndian_string[ 4 ] = 0x00;
   UCS2LittleEndian_string[ 5 ] = 0x00;

   UCS2LittleEndian_string_length = 6;
  }

 PutStringIntoClipboard( Enhancer.Application,
                         Common_string,
                         UCS2LittleEndian_string,
                         UCS2LittleEndian_string_length,
                         Mozilla_internal_format );

 // Посылаем в очередь окна сообщение WM_MARK. При его получении можно
 // будет изменить состояние клавиатуры и направить в окно сообщение WM_CHAR.
 HMQ Message_queue = WinQueryWindowULong( Input_window, QWL_HMQ );
 WinPostQueueMsg( Message_queue, WM_MARK, (MPARAM) MRK_POST_CTRL_V, (MPARAM) Input_window );

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