Beispiel #1
0
void os2FrameWindow::SetWindowListVisibility(bool aState)
{
  HSWITCH hswitch = WinQuerySwitchHandle(mFrameWnd, 0);
  if (hswitch) {
    SWCNTRL swctl;
    WinQuerySwitchEntry(hswitch, &swctl);
    swctl.uchVisibility = aState ? SWL_VISIBLE : SWL_INVISIBLE;
    swctl.fbJump        = aState ? SWL_JUMPABLE : SWL_NOTJUMPABLE;
    WinChangeSwitchEntry(hswitch, &swctl);
  }
}
void OS2Factory::removeFromTaskBar()
{
    WinSetWindowPos( m_hParentWindow, NULLHANDLE, 0, 0, 0, 0, SWP_HIDE );

    HSWITCH hswitch = WinQuerySwitchHandle( m_hParentWindow, 0 );

    SWCNTRL swctl;
    WinQuerySwitchEntry( hswitch, &swctl );
    swctl.uchVisibility = SWL_INVISIBLE;
    WinChangeSwitchEntry( hswitch, &swctl );

    WinSetWindowPos( m_hParentWindow, NULLHANDLE, 0, 0, 0, 0,
                     SWP_ACTIVATE | SWP_SHOW );
}
void SwitchTo( TASKDATA* data )
{
  SWP swp;

  if( WinQueryWindowPos( data->hWindow, &swp ))
  {
    if( swp.fl & ( SWP_HIDE | SWP_MINIMIZE ))
    {
      // window is hidden or minimized: restore and activate
      HSWITCH hsw = WinQuerySwitchHandle( data->hWindow, data->pid );

      if( hsw )
      {
        // first check if the thing is hidden
        if( swp.fl & SWP_HIDE ) {
            WinSetWindowPos( data->hWindow, 0, 0, 0, 0, 0, SWP_SHOW );
        }

        if( !WinSwitchToProgram( hsw ))
        {
          // OK, now we have the program active, but it's
          // probably in the background...
          WinSetWindowPos( data->hWindow, HWND_TOP, 0, 0, 0, 0,
                           SWP_SHOW | SWP_ACTIVATE | SWP_ZORDER );
        }
      }
    }
    else
    {
      // not minimized: see if it's active
      HWND hwndActive = WinQueryActiveWindow( HWND_DESKTOP );

      if( hwndActive != data->hWindow )
      {
        // not minimized, not active:
        WinSetActiveWindow( HWND_DESKTOP, data->hWindow );
      }
    }
  }
}
SOM_Scope void  SOMLINK ODExclusiveFocusModuleSetFocusOwnership(ODExclusiveFocusModule *somSelf, Environment *ev,
		ODTypeToken focus,
		ODFrame* frame)
{
    ODExclusiveFocusModuleData *somThis = ODExclusiveFocusModuleGetData(somSelf);
    ODExclusiveFocusModuleMethodDebug("ODExclusiveFocusModule","SetFocusOwnership");
#if !defined(_PLATFORM_OS2_) && !defined(_PLATFORM_WIN32_)
	ODFacet* facet = kODNULL;
	ODFrameFacetIterator* facets = kODNULL;
#endif
	SOM_TRY
	
		if (focus == _fSelectionFocus)
		{
			if (_fFrame)
				_fFrame->InvalidateActiveBorder(ev);
#if !defined(_PLATFORM_OS2_) && !defined(_PLATFORM_WIN32_)
				TempODFrame contFrame = _fFrame->AcquireContainingFrame(ev); // -- T‚ tempobj'd
				if ((ODFrame*) contFrame )
				{
					TempODPart contPart = contFrame->AcquirePart(ev); // -- T‚ tempobj'd
					facets = _fFrame->CreateFacetIterator(ev);
					for ( facet = facets->First(ev);
					facets->IsNotComplete(ev);
							facet = facets->Next(ev) )
					{
						ODShape* border = contPart->AdjustBorderShape(ev, facet, kODNULL);
						ODReleaseObject(ev, border);
					}
					ODDeleteObject(facets);
				}
			}
			// Note:  window->Update(ev);
			if (frame)
				frame->DrawActiveBorder(ev);
			ResolveClipboardPromises(ev, _fFrame, _fSession);
#endif //  !defined(_PLATFORM_OS2_) && !defined(_PLATFORM_WIN32_)
#ifdef _PLATFORM_OS2_  // [124872] - ced  OS2 TASK LIST MODIFICATION CODE
     {
#if 0  // was not implemented in OS2 code
// if selection focus changes update the Title bar and Window List
// with the active editor name.
	 USHORT nopreferredparteditor, rc;
	 ULONG size=0;
	// Str255 edt;
	 CHAR   string[256];
	 CHAR * edt, *str ;
	 ODName * name;
//       HWND hwndplat = _fSession->GetPlatformWindow(ev);                          // ced
	 TempODWindow aWindow = frame->AcquireWindow(ev);
	 HWND hwndplat = aWindow->GetPlatformWindow(ev); // ced

	 ODNameSpaceMana ger*  nsm = _fSession->GetNameSpaceManager(ev);
	 TempODPart party1 = frame->AcquirePart(ev);
	 ODStorageUnit * psu = party1->GetStorageUnit(ev);
	 ODType  pEdit =(ODType) ODGetISOStrProp(ev,psu, kODPropPreferredEditor,kODEditor,kODNULL,&size);
//                        GetPreferredEditorForPart(psu,&nopreferredparteditor);
	 rc = GetUserEditorFromEditor(nsm, pEdit,&name);
#ifdef _UNICODE_
      convert = ConvertFromUnicode(((ODPlainITextData *)name->text._buffer)->theText,
				   CharStr,
				   UniStrlen(((ODPlainITextData *)name->text._buffer)->theText),
				   co);
      edt = CharStr;
#else
      edt =  ((ODPlainITextData *)name->text._buffer)->theText;
#endif
// get the root part
      ODFrame * contFrame, * newFrame;
      SWCNTRL swctl;
      newFrame = frame;
      do {
	 contFrame = newFrame;
	 newFrame = contFrame->AcquireContainingFrame(ev);

      } while ( newFrame ); /* enddo */
      TempODPart party2 = contFrame->AcquirePart(ev);
// get window list data
      HSWITCH  hswitch = WinQuerySwitchHandle(hwndplat,0);
      WinQuerySwitchEntry ( hswitch, &swctl);
      strcpy (string,swctl.szSwtitle);
      USHORT i=0;
      while (string[i] != '\0') {
	if (string[i]== '-' ) {
	   if ((string[i-1]==' ')&&(string[i+1]==' ')) {
	      break;
	   } /* endif */
	} /* endif */
	i++;
      } /* endwhile */
      string[i] = '\0';

//    get part name
      ODName * pname = kODNULL;            // [127087]
      pname = ODGetPOName(ev,party2,pname);    // [127087]
		if (pname != kODNULL)
			{
			str =  GetCStringFromIText(pname);   // [127087]
			strcat(string, " - ");
			strcat(string,str);
	 DisposeIText(pname);                 // [127087]
			}
		strcat(string, " - ");
		strcat(string,edt);
	   // change the Window List Text
      strcpy(swctl.szSwtitle,string);
//    WinChangeSwitchEntry (hswitch, &swctl);
//      WinSetWindowText(hwndplat,string);
#endif // #if 0
      frame->DrawActiveBorder(ev);
    }
      frame->DrawActiveBorder(ev);
#endif // _PLATFORM_OS2

#ifdef _PLATFORM_WIN32_
 // ********* OLE Interop start ******
  TempODPart part = frame->AcquirePart(ev);
  OleWrapper* wrapper = ODOLEManager::GetShell()->GetDocumentManagerOfDraft(ev, part->GetStorageUnit(ev)->GetDraft(ev))->GetOleWrapper(ev);
  if (wrapper) {
     if ((wrapper->fWFlg & WFLG_UIACTIVATED) && (wrapper->fActiveDocumentWindow == wrapper->fRootDocumentWindow))
          wrapper->ActiveFocusChanging(frame);
  }
 // **********OLE Interop end
   if(frame)
      frame->DrawActiveBorder(ev);
#endif // _PLATFORM_WIN32_

  }  // end for - if (focus == _fSelectionFocus)
// 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;
}
// Show_items - скрыть или показать строки, Hide_known_applications - скрыть известные приложения.
VOID Remover_ShowAllItemsInSwitchList( BYTE Show_or_hide, BYTE Hide_known_applications = 0 )
{
 // Окно оболочки прятать нельзя.
 PCHAR Shell_window_item = NULL;

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

   if( Shell_window != NULLHANDLE )
    {
     // Узнаем, есть ли оно в списке окон.
     HSWITCH Switch_handle = WinQuerySwitchHandle( Shell_window, NULLHANDLE );
     SWCNTRL Task; bzero( &Task, sizeof( SWCNTRL ) );

     // Если его нет - добавляем его.
     if( Switch_handle == NULLHANDLE )
      {
       Task.hwnd = Shell_window;
       GetDefaultShellTitle( Task.szSwtitle );

       Task.uchVisibility = SWL_VISIBLE;
       Task.fbJump = SWL_JUMPABLE;

       HSWITCH Switch_handle = WinAddSwitchEntry( &Task );
      }
     // Если оно есть - делаем его видимым в списке.
     else
      {
       WinQuerySwitchEntry( Switch_handle, &Task );

       if( Task.uchVisibility != SWL_VISIBLE || Task.fbJump != SWL_JUMPABLE )
        ShowItemInSwitchList( Switch_handle, Task, 1 );
      }

     // Запоминаем строку.
     Shell_window_item = Task.szSwtitle;
    }
  }

 // Узнаем список окон.
 PSWBLOCK SWBlock = NULL; QuerySwitchList( &SWBlock );

 // Показываем или скрываем строки.
 {
  INT Count; INT Item_count;

  for( Count = 0; Count < SWBlock->cswentry; Count ++ )
   {
    BYTE Hide_this_item = 0;

    // Скрываем приложения, известные расширителю.
    if( Hide_known_applications )
     {
      HWND Frame_window = SWBlock->aswentry[ Count ].swctl.hwnd;

      if( !Hide_this_item && IsECenterWindow( Frame_window ) ) Hide_this_item = 1;
      if( !Hide_this_item && IsWarpCenterWindow( Frame_window ) ) Hide_this_item = 1;
      if( !Hide_this_item && IsLaunchPadWindow( Frame_window ) ) Hide_this_item = 1;
      if( !Hide_this_item && IslSwitcherWindow( Frame_window ) ) Hide_this_item = 1;

      if( !Hide_this_item && IsVIOWindow( Frame_window ) )
       {
        PCHAR Title = SWBlock->aswentry[ Count ].swctl.szSwtitle;

        if( strc( Title, Remover.Settings.DDNS ) ||
            strc( Title, Remover.Settings.DHCP ) ||
            strc( Title, Remover.Settings.BINL ) ) Hide_this_item = 1;
       }

      if( !Hide_this_item && ShellIsWPS() )
       {
        if( WindowIsUsedTo( DO_IMPROVE_WORKPLACE, Frame_window ) )
         if( !WindowIsCreatedBy( APP_NICE, Frame_window ) )
          Hide_this_item = 1;

        if( !Hide_this_item && IsSysTrayWindow( Frame_window ) ) Hide_this_item = 1;
        if( !Hide_this_item && IsSmartBarWindow( Frame_window ) ) Hide_this_item = 1;
       }
     }

    // Скрываем приложения, заданные пользователем.
    for( Item_count = 0; Item_count < 8; Item_count ++ )
     {
      PCHAR Item_name = Remover.Settings.WinListNames.Remove_from_list_1_name;
      if( Item_count == 1 ) Item_name = Remover.Settings.WinListNames.Remove_from_list_2_name;
      if( Item_count == 2 ) Item_name = Remover.Settings.WinListNames.Remove_from_list_3_name;
      if( Item_count == 3 ) Item_name = Remover.Settings.WinListNames.Remove_from_list_4_name;
      if( Item_count == 4 ) Item_name = Remover.Settings.WinListNames.Remove_from_list_5_name;
      if( Item_count == 5 ) Item_name = Remover.Settings.WinListNames.Remove_from_list_6_name;
      if( Item_count == 6 ) Item_name = Remover.Settings.WinListNames.Remove_from_list_7_name;
      if( Item_count == 7 ) Item_name = Remover.Settings.WinListNames.Remove_from_list_8_name;

      if( Item_name[ 0 ] != 0 )
       {
        PCHAR Title = SWBlock->aswentry[ Count ].swctl.szSwtitle;

        #ifndef INCLUDED_BY_SHELL

        if( Shell_window_item != NULL )
         if( strc( Title, Shell_window_item ) ) continue;

        #endif

        if( strc( Title, Item_name ) ) Hide_this_item = 1;
       }

       if( Hide_this_item ) break;
     }

    // Скрываем строки.
    if( Hide_this_item )
     {
      HSWITCH Switch_handle = SWBlock->aswentry[ Count ].hswitch;
      SWCNTRL Task = SWBlock->aswentry[ Count ].swctl;

      ShowItemInSwitchList( Switch_handle, Task, Show_or_hide );
     }
   }
 }

 // Освобождаем память.
 FreeSwitchListMemory( SWBlock ); SWBlock = NULL;

 // Возврат.
 return;
}
int spawnve(int mode, const char *name, char * const argv[],
            char * const envp[])
{
  int i, j, l, n, prefix_len = 0;
  char *ext, *tmp, *arg1, *execname, *p_arg, *p_env, *prefix = NULL;
  char runtype, freeexec = 0, hswValid = 0, quoteargs = 1;
  ULONG appflags;
  const char * const *p;
  unsigned int runflags = 0;
  int retcode = -1;
  char errbuf[MAXNAMLEN + 1], queue[MAXNAMLEN + 1];
  SWCNTRL swc;
  HSWITCH vioHSW;

  errno = ENOENT;

  /* EMX crashes on very long filenames... */
  if (strlen (name) > MAXNAMLEN - 4)
  {
   errno = ENAMETOOLONG;
   return -1;
  }

  /* Find extension ordinal in exec_ext array */
  ext = _getext2(name);
  for (i = 0; i < EXEC_EXT_COUNT; i++)
  {
   if (strcmp(ext, exec_ext[i]) == 0)
    goto found;
  }
  if (access(name, F_OK) == 0)
   errno = ENOEXEC;
  return -1;

found:
 {
  PTIB tb;
  PPIB pb;

  /* Determine our session type */
  if ((DosGetInfoBlocks(&tb, &pb) == NO_ERROR) &&
      (vioHSW = WinQuerySwitchHandle(NULLHANDLE, pb->pib_ulpid)) &&
      (WinQuerySwitchEntry(vioHSW, &swc) == NO_ERROR))
   hswValid = 1;
 }

 switch (mode & 0xFF)
 {
  case P_WAIT:
   runflags |= spawn_WAIT; break;
  case P_PM:
   runflags |= spawn_SESSION | spawn_TYPE_PM; break;
  case P_OVERLAY:
   runflags |= spawn_WAIT | spawn_OVERLAY; break;
  case P_DETACH:
   runflags |= spawn_DETACH; break;
 }

 if (((runtype = exec_run[i]) == 0) &&
     (DosQueryAppType((PSZ)name, &appflags) == NO_ERROR) &&
     ((runflags & spawn_DETACH) == 0) &&
     (hswValid))
 {
  /* Compare to application type */
  switch (appflags & 7)
  {
   case FAPPTYP_NOTSPEC:  /* Methinks its a DOS proggy */
   {
    if (appflags & FAPPTYP_DOS)
     if (swc.bProgType == PROG_FULLSCREEN)
      runflags |= (spawn_SESSION | spawn_TYPE_VDM);
     else
      runflags |= (spawn_SESSION | spawn_TYPE_WINDOWEDVDM);
    else
     runflags |= (spawn_SESSION | spawn_TYPE_DEFAULT);
    break;
   }
   case FAPPTYP_NOTWINDOWCOMPAT:
   {
    if (swc.bProgType != PROG_FULLSCREEN)
     runflags |= (spawn_SESSION | spawn_TYPE_FULLSCREEN);
    break;
   }
   case FAPPTYP_WINDOWCOMPAT:
   {
    /* That'll do it */
    break;
   }
   case FAPPTYP_WINDOWAPI:
   {
    runflags |= (spawn_SESSION | spawn_TYPE_PM);
    break;
   }
   default:
   {
    runtype = 1; /* Let $COMSPEC decide what to do */
    break;
   }
  }
 }

fallback:
 switch (runtype)
 {
  case 0:
directrun:
   if ((runflags & spawn_SESSION) &&
       (((runflags & spawn_TYPE) == spawn_TYPE_VDM) ||
        ((runflags & spawn_TYPE) == spawn_TYPE_WINDOWEDVDM)))
   {
    /* DOS command interpreter does not understand '/'s */
    execname = savestring((char *)name);
    freeexec = 1;
    for (tmp = execname; *tmp; tmp++)
     if (*tmp == '/') *tmp = '\\';
   } else
    execname = (char *)name;
   break;
  case 1:
   execname = get_string_value ("COMSPEC");
   if (!execname)
   {
    internal_error("COMSPEC variable not defined");
    errno = EACCES;
    return -1;
   }
   prefix_len = strlen(execname) + 1;
   prefix = alloca(prefix_len + 2 + 1 + strlen(name) + 1);
   strcpy(prefix, execname);
   emx_deunixify(prefix);
   strcpy((char *)&prefix[prefix_len - 1], " /c ");
   prefix_len += 2 + 1;
   strcpy((char *)&prefix[prefix_len], name);
   prefix_len += strlen(name) + 1;
   break;
  case 2:
  default:
  {
   /* We must define HAVE_HASH_BANG_EXEC since we`re processing #! here */
   FILE *f;
   char line[MAXNAMLEN + 3];
   line[0] = 0;
   if (!(f = fopen(name, "rt")))
   {
    errno = ENOENT;
    return -1;
   };
   fgets((char *)&line, sizeof(line), f);
   fclose(f);
   if (line[0] != '#')
    /* Try to run as regular executable */
    goto directrun;
   if (line[1] != '!')
   {
    /* Run script using current shell */
    strcpy((char *)&line, "#! ");
    strcat((char *)&line, shell_name);
   }
   n = strlen(line);
   while ((n > 0) && ((line[n - 1] < ' ') || (whitespace(line[n])))) n--;
   for (i = 2; whitespace(line[i]) && i < n; i++)
    ;
   for (j = i; (!whitespace(line[j])) && j < n; j++)
    ;
   l = i; j++;
   tmp = xmalloc(j - i);
   _strncpy(tmp, (char *)&line[i], j - i);

   execname = find_user_command(tmp);
   free(tmp);
   freeexec = 1;

   prefix_len = n - l + 1 + 1 + strlen(name);
   prefix = alloca(prefix_len + 1);
   _strncpy(prefix, (char *)&line[l], n - l + 1);
   strcat(prefix, " ");
   strcat(prefix, name);
   break;
  }
 }

 if ((execname == NULL) || (access(execname, F_OK) != 0))
 {
  if (execname == NULL)
  {
   errno = ENOEXEC;
   return -1;
  }
  execname = savestring(execname);
  freeexec = 1;
  if ((ext_file_status(&execname) & FS_EXISTS) == 0)
  {
   free(execname);
   errno = ENOENT;
   return -1;
  }
 }

 {
  char *qlist = get_string_value ("BASH_NOQUOTEARGS");
  char *tmp, *name = _getname (execname);
  int namelen;

  tmp = _getext (name);
  namelen = (tmp ? (int) (tmp - name) : strlen (name));

  while (qlist)
  {
   tmp = strchr (qlist, ';');
   if (!(j = tmp ? (int) (tmp - qlist) : strlen (qlist)))
    break;
   if ((namelen == j) &&
       (memicmp (qlist, name, namelen) == 0))
   {
    quoteargs = 0;
    break;
   }
   qlist += j;
   while (qlist[0] == ';')
    qlist++;
  }
 }

 /* Prepare command-line string */
 j = prefix_len + 2;
 for (i = 0; i <= 1; i++)
 {
  for (p = (const char **)argv; *p != NULL; ++p)
  {
   if (p != (const char **)argv)
    if (i == 0)			// Add a space before args starting from 1
     j++;
    else
     strcat(p_arg, " ");
   else
    if (prefix_len)
     continue;			// Prefix already contains argv[0]

   // If argv[i] contains a space or tab, we should put it in quotes
   if (strchr(*p, ' ') || strchr(*p, '\t'))
    if (i == 0)
     j += 1 + (quoteargs ? q_strlen(*p) : strlen(*p)) + 1;
    else
    {
     strcat(p_arg, "\"");
     if (quoteargs)
      q_strcat (p_arg, *p);
     else
      strcat (p_arg, *p);
     strcat(p_arg, "\"");
    }
   else
    // If we`re running a EMX program, we should backquote all '"'s in argv[i]
    if (i == 0)
     j += (quoteargs ? q_strlen(*p) : strlen(*p));
    else
     if (quoteargs)
      q_strcat(p_arg, *p);
     else
      strcat(p_arg, *p);
  }
  if (i == 0)
  {
   p_arg = alloca(j);
   if (prefix_len)
   {
    memcpy(p_arg, prefix, prefix_len);
    p_arg[prefix_len] = ' ';
    p_arg[prefix_len + 1] = 0;
   } else
    *p_arg = 0;
  }
 }
 p_arg[strlen(p_arg) + 1] = 0;

#if 0
 printf("quoteargs = %d\n", quoteargs);
 printf("exec{%s}\n", execname);
 printf("args{%s}\n", p_arg);
#endif

 for (arg1 = p_arg; !whitespace(*arg1) && *arg1; arg1++) ;
 *arg1++ = 0;

 /* Prepare environment */
 j = 1;
 for (p = (const char * const *)envp; *p != NULL; ++p)
  j += strlen (*p) + 1;
 p_env = tmp = alloca(j);
 for (p = (const char * const *)envp; *p != NULL; ++p)
 {
  i = strlen (*p);
  memcpy(tmp, *p, i+1);
  tmp += i+1;
 }
 *tmp = 0;

 if (runflags & spawn_SESSION) /* Use DosStartSession */
 {
  HQUEUE hq;

  /* Termination queue management */
  sprintf((char *)&queue, "\\QUEUES\\bash%d", getpid());
  if (DosCreateQueue(&hq, QUE_FIFO | QUE_CONVERT_ADDRESS, (PSZ)queue) == NO_ERROR)
  {
   STARTDATA sd;
   ULONG sid,pid;
   APIRET r;

   memset(&sd, 0, sizeof(sd));
   sd.Length = sizeof(sd);
   sd.Related = (runflags & spawn_WAIT ? SSF_RELATED_CHILD : SSF_RELATED_INDEPENDENT);
   sd.FgBg = SSF_FGBG_FORE;
   sd.PgmName = execname;
   sd.PgmInputs = arg1;
   sd.TermQ = (PBYTE)&queue;
   sd.Environment = p_env;
   sd.InheritOpt = SSF_INHERTOPT_PARENT;
   sd.SessionType = (runflags & spawn_TYPE) >> 16;
   sd.ObjectBuffer = (PSZ)&errbuf;
   sd.ObjectBuffLen = sizeof(errbuf);
#if 0
   sd.PgmControl = SSF_CONTROL_NOAUTOCLOSE;
#endif

   r = DosStartSession(&sd, &sid, &pid);

   if (r == NO_ERROR || r == ERROR_SMG_START_IN_BACKGROUND)
   {
    if (runflags & spawn_WAIT)
    {
     REQUESTDATA rd;
     ULONG Length;
     PUSHORT Info = NULL;
     BYTE Priority;
     ULONG oldVis, oldJump;
     SWP oldpos;

     if (hswValid)
     {
      /* Exclude session from task list */
      oldVis = swc.uchVisibility; swc.uchVisibility = SWL_INVISIBLE;
      oldJump = swc.fbJump; swc.fbJump = SWL_NOTJUMPABLE;
      WinChangeSwitchEntry(vioHSW, &swc);

      /* Minimize session */
      WinQueryWindowPos(swc.hwnd, &oldpos);
      if ((oldpos.fl & SWP_MINIMIZE) == 0)
       WinPostMsg(swc.hwnd, WM_SYSCOMMAND, (MPARAM)SC_MINIMIZE, MPFROM2SHORT(CMDSRC_MENU, FALSE));
     }

     DosReadQueue(hq, &rd, &Length, (PPVOID)&Info, 0,
                  DCWW_WAIT, &Priority, 0);

     if (hswValid)
     {
      /* Restore jumpable & visible status */
      swc.uchVisibility = oldVis;
      swc.fbJump = oldJump;
      WinChangeSwitchEntry(vioHSW, &swc);

      /* Restore session */
      if ((oldpos.fl & SWP_MINIMIZE) == 0)
      {
       WinPostMsg(swc.hwnd, WM_SYSCOMMAND, (MPARAM)SC_RESTORE, MPFROM2SHORT(CMDSRC_MENU, FALSE));
       WinSetWindowPos(swc.hwnd, oldpos.hwndInsertBehind, oldpos.x, oldpos.y,
                       oldpos.cx, oldpos.cy, oldpos.fl);
      }
     }

     retcode = Info[1];
    } else
     retcode = pid;
   } else
    internal_error("Execution failed because of module \"%s\"", (char *)&errbuf);
   DosCloseQueue(hq);
  } else
// Поток приложения вызывает WindowProc всякий раз, когда для окна есть сообщение.
// Window - окно, Message - сообщение, *_parameter - данные, которые передаются вместе с сообщением.
MRESULT EXPENTRY Installer_ClientWindowProc( HWND Window, ULONG Message, MPARAM First_parameter, MPARAM Second_parameter )
{
 switch( Message )
  {
   // Выполняем действия при создании окна.
   case WM_CREATE:
    {
     WinPostMsg( Window, MY_CREATE, 0, 0 );
    }
   return 0;

   case MY_CREATE:
    {
     // Задаем заголовок окна приложения.
     if( Installer.Code_page == RUSSIAN ) strcpy( Installer.Frame_window_title, StrConst_RU_Title );
     else strcpy( Installer.Frame_window_title, StrConst_EN_Title );

     WinSetWindowText( Installer.Frame_window, Installer.Frame_window_title );

     // Устанавливаем картинку в левом верхнем углу окна.
     WinSendMsg( Installer.Frame_window, WM_SETICON, (MPARAM) WinLoadPointer( HWND_DESKTOP, NULLHANDLE, 1 ), 0 );

     // Задаем расположение окна.
     {
      INT X_Screen = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
      INT Y_Screen = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );

      INT Window_width  = X_Screen / 3; if( X_Screen < 1024 ) Window_width  *= 1.25;
      INT Window_height = Y_Screen / 3; if( X_Screen < 1024 ) Window_height *= 1.25;

      INT Window_position_X = ( X_Screen - Window_width ) / 2;
      INT Window_position_Y = ( Y_Screen - Window_height ) / 2 + ( Y_Screen - Window_height ) / 4 / 2;

      WinSetWindowPos( Installer.Frame_window, HWND_TOP, Window_position_X, Window_position_Y, Window_width, Window_height, SWP_ZORDER | SWP_MOVE | SWP_SIZE | SWP_NOADJUST );
      WinSetActiveWindow( HWND_DESKTOP, Installer.Frame_window );
     }

     // Добавляем его в список окон.
     {
      SWCNTRL Task; HSWITCH Switch_handle = NULLHANDLE;

      bzero( &Task, sizeof( SWCNTRL ) );
      Task.hwnd = Installer.Frame_window;
      Task.hwndIcon = (HPOINTER) WinSendMsg( Installer.Frame_window, WM_QUERYICON, 0, 0 );
      WinQueryWindowProcess( Installer.Frame_window, &Task.idProcess, NULL );
      strcpy( Task.szSwtitle, Installer.Frame_window_title );

      Task.uchVisibility = SWL_VISIBLE;
      Task.fbJump = SWL_JUMPABLE;

      Switch_handle = WinCreateSwitchEntry( Installer.Application, &Task );
      WinChangeSwitchEntry( Switch_handle, &Task );
     }

     // Создаем поля ввода в окне рабочей области.
     ClientWindow_CreatePage( Installer.Client_window );
    }
   return 0;

   // Передвигаем поля ввода.
   case MY_APPLY_LAYOUT:
    {
     LitApplyLayout( &Client_Window.Layout );
    }
   return 0;

   // Включаем и отключаем поля ввода.
   case MY_ENABLE_BUTTONS:
    {
     ULONG Action = (ULONG) First_parameter;

     WinEnableWindow( WinWindowFromID( WinWindowFromID( Window, Client_Window.Settings.Buttons_brick_ID ), Client_Window.Settings.Install_button_ID ), Action );
     WinEnableWindow( WinWindowFromID( WinWindowFromID( Window, Client_Window.Settings.Buttons_brick_ID ), Client_Window.Settings.Remove_button_ID ), Action );
     WinEnableWindow( WinWindowFromID( WinWindowFromID( Window, Client_Window.Settings.Buttons_brick_ID ), Client_Window.Settings.Cancel_button_ID ), Action );

     if( !Action )
      WinSendMsg( WinWindowFromID( Installer.Frame_window, FID_SYSMENU ), MM_SETITEMATTR, MPFROM2SHORT( SC_CLOSE, INCLUDE_SUBMENUS ), MPFROM2SHORT( MIA_DISABLED, MIA_DISABLED ) );
     else
      WinSendMsg( WinWindowFromID( Installer.Frame_window, FID_SYSMENU ), MM_SETITEMATTR, MPFROM2SHORT( SC_CLOSE, INCLUDE_SUBMENUS ), MPFROM2SHORT( MIA_DISABLED, 0 ) );
    }
   return 0;

   // Обрабатываем нажатия на кнопки.
   case WM_COMMAND:
    {
     ULONG WM_Control_Button_ID = SHORT1FROMMP( First_parameter );

     if( WM_Control_Button_ID == Client_Window.Settings.Install_button_ID )
      {
       StartInstallerThread( NIA_INSTALL );
      }

     if( WM_Control_Button_ID == Client_Window.Settings.Remove_button_ID )
      {
       StartInstallerThread( NIA_REMOVE );
      }

     if( WM_Control_Button_ID == Client_Window.Settings.Cancel_button_ID )
      {
       WinPostMsg( Installer.Frame_window, WM_SYSCOMMAND, (MPARAM) SC_CLOSE, 0 );
      }
    }
   return 0;

   // Закрашиваем пространство окна.
   case WM_PAINT:
    {
     RECT Rectangle = {0};
     HPS Presentation_space = WinBeginPaint( Window, 0, &Rectangle );

     if( Presentation_space )
      {
       LONG Color_table[ 256 ]; bzero( Color_table, sizeof( Color_table ) );
       GpiQueryLogColorTable( Presentation_space, 0, 0, 256, Color_table );

       LONG Color_index = ( 256 - 1 );
       WinQueryPresParam( Window, PP_BACKGROUNDCOLOR, 0, NULL, sizeof( Color_table[ Color_index ] ), &Color_table[ Color_index ], QPF_NOINHERIT );
       GpiCreateLogColorTable( Presentation_space, 0, LCOLF_CONSECRGB, 0, 256, Color_table );

       WinFillRect( Presentation_space, &Rectangle, Color_index );
       WinEndPaint( Presentation_space );
      }
    }
   return 0;

   // Сообщаем окну рамки, что содержимое окна рабочей области закрашивать не следует.
   case WM_ERASEBACKGROUND:
   return (MPARAM) 0;

   // Выполняем действия при нажатии на кнопку закрытия окна.
   case WM_CLOSE:
    {
     // Убираем окно приложения из списка окон.
     WinRemoveSwitchEntry( WinQuerySwitchHandle( Installer.Frame_window, 0 ) );

     // Передаем сообщение обработчику.
     WinDefWindowProc( Window, Message, First_parameter, Second_parameter );
    }
   return 0;
  }

 // Возврат.
 return WinDefWindowProc( Window, Message, First_parameter, Second_parameter );
}