Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  01:28[Войти] | [Зарегистрироваться]
Ответ на вопрос № 70742

19-05-2009 04:13
Здравствуйте!
Как сделать чтобы окно програмы всегда было на весь экран и его нельзя было свернуть?

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

09-06-2009 13:57
Если создать новый десктоп, то никуда юзер с него не переключится. Можете попробовать:

const
  cOldDesktopName = 'Default';
  cNewDesktopName = 'Pokus';

procedure TForm1.FormDestroy(Sender: TObject);
begin
  CloseDesk(OldD);
  CloseDesk(NewD);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  OldD := OpenDesk(cOldDesktopName);
  NewD := OpenDesk(cNewDesktopName);
  if NewD = 0 then
    NewD := CreateDesk(cNewDesktopName);

  CurrentD := GetDeskName(GetCurrentDesk);
  if CurrentD = cOldDesktopName then
    bSwitchToOldD.Enabled := False
  else
    bSwitchToNewD.Enabled := False;
end;

procedure TForm1.bSwitchToOldDClick(Sender: TObject);
begin
  SetLastError(0);
  if SwitchDesk(OldD) then
    Close
  else
    Label4.Caption := 'Cannt switch to ' + IntToStr(OldD) + #13#10 +
      SysErrorMessage(GetLastError);
end;

procedure TForm1.bSwitchToNewDClick(Sender: TObject);
begin
  StartOnDesk(paramstr(0), '', cNewDesktopName);
  SwitchDesk(NewD);
end;

И юнит обертка над системными функциями:

unit DesktopUtils;

interface

uses
  Windows, SysUtils;

function CreateDesk(Name: string): HDESK;
function OpenDesk(Name: string): HDESK;
function SwitchDesk(Desk: HDESK): Boolean;
function CloseDesk(Desk: HDESK): Boolean;
function GetCurrentDesk: HDESK;
function GetDeskName(Desk: HDESK): string;
function StartOnDesk(ApplicationName, CommandLine, DeskName: string): Boolean;

implementation

function CreateDesk(Name: string): HDESK;
var
  sa:_SECURITY_ATTRIBUTES;
begin
  FillChar(sa, SizeOf(sa), 0);
  sa.nLength:= sizeof(sa);
  sa.lpSecurityDescriptor:= Nil;
  sa.bInheritHandle:= True;

  Result := CreateDesktop(PChar(Name), Nil, Nil, 0, GENERIC_ALL, @sa);
end;

function OpenDesk(Name: string): HDESK;
begin
  Result := OpenDesktop(PChar(Name), 0, True, GENERIC_ALL);
end;

function SwitchDesk(Desk: HDESK): Boolean;
begin
  Result := SwitchDesktop(Desk);
end;

function CloseDesk(Desk: HDESK): Boolean;
begin
  Result := CloseDesktop(Desk);
end;

function GetCurrentDesk: HDESK;
var
  thr: Integer;
begin
  thr := GetCurrentThreadId;
  Result := GetThreadDesktop(thr);
end;

function GetDeskName(Desk: HDESK): string;
var
  buf: PChar;
  needed: Cardinal;
begin
  buf := AllocMem(1024);
  if not GetUserObjectInformation(Desk, UOI_NAME, buf, 1024, needed) then
  begin
    FreeMem(buf);
    buf := AllocMem(needed);
    GetUserObjectInformation(Desk, UOI_NAME, buf, needed, needed);
  end;
  Result := buf;
  FreeMem(buf);
end;

function StartOnDesk(ApplicationName, CommandLine, DeskName: string): Boolean;
var
  sa:_SECURITY_ATTRIBUTES;
  sti:STARTUPINFO;
  pri:_PROCESS_INFORMATION;
begin
  FillChar(sa, SizeOf(sa), 0);
  sa.nLength:= sizeof(sa);
  sa.bInheritHandle:= true;

  FillChar(sti, SizeOf(sti), 0);
  sti.cb:= SizeOf(sti);
  sti.lpDesktop:= PChar(DeskName);
  sti.dwFillAttribute:= FOREGROUND_BLUE;

  FillChar(pri, SizeOf(pri), 0);

  Result := CreateProcess(PChar(ApplicationName), PChar(CommandLine), @sa,
    @sa, True, CREATE_SEPARATE_WOW_VDM, Nil, Nil, sti, pri);
end;

end.


Смысл в том, что как только поток создает первое окно, он намертво приклеивается к текущему десктопу. А поскольку VCL штука однопоточная, то на втором десктопе приходится запускать вторую копию своего приложения. Остальное думаю несложно найти в справке.

09-06-2009 13:09 | Сообщение от автора вопроса
Блин, все же не все работает. Если форма показывает другую форму (модально) или выводить сообщение (например ShowMessage), то можно легко переключиться на любое другое приложение.
:(

20-05-2009 05:58 | Сообщение от автора вопроса
Shaman, спасибо. Все вроде бы работает.

20-05-2009 04:59 | Сообщение от автора вопроса
Увы, но если уровень владения компьютером пользователя выше уровня администратора, то защита по определению ненадежна.
Нет цели создать абсолютно надежную монопольную программу... Как оказывается много пользователей (учителей) используя эту функцию тестирую учеников (не профи и не админов) могут упростить себе жизнь.
Т.е. тут частный случай - пользователи и одни и другие не профи и не админы.

20-05-2009 04:18
>>> Увы, но это реалии многих средних учебных заведений
Увы, но если уровень владения компьютером пользователя выше уровня администратора, то защита по определению ненадежна. Какую бы замечательную программы Вы ни написали. Абсолютно надежным будет только вариант написания собственной ОС, заточенной под Вашу конкретную задачу. Все остальное можно будет обойти, если не предусмотреть защиты на уровне ОС.

20-05-2009 02:56 | Сообщение от автора вопроса
2 Geo
Многие пользователи на такое не способны (и человека который бы это сделал нет). Поставить птичку "монопольный режим" при проверке еще смогут, а выполнить какие-либо администраторские функции нет. Увы, но это реалии многих средних учебных заведений.

20-05-2009 02:55
...и вообще, пишите FullScreen-программку с DirectX - тогда даже меню Пуск не будет...

20-05-2009 02:34
В упор не пойму, зачем пытаться подменять в своей программе административные механизмы, которые уже реализованы в Windows. Причем гарантированно получится хуже и менее надежно.

Пусть администратор заведет дополнительного пользователя, которому будет запрещено все, кроме запуска Вашей программы. И нет никаких проблем. И не надо думать как заткнуть вмсе дыры, потому что проверяемый гарантированно не сможет ничего больше запустить, даже если свернет Вашу программу.

20-05-2009 02:09
Тогда есть еще вариант с созданием отдельного десктопа (CreateDesktop, SwitchDesktop, OpenDesktop), и запуском на нем второй копии программы :)

20-05-2009 02:00
Зачем все эти фокусы? Если нужно запретить доступ к рабочему столу, то достаточно написать свой шелл и подменить им стандартный. Тогда при запуске винды в качестве рабочего стола будет ваша программа.
Программа должна включать монопольный режим при необходимости (во время работы) и выключать его, а не всегда.

20-05-2009 01:51 | Сообщение от автора вопроса
А если два экземпляра программы?
два экземпляра запустить нельзя (это реализовано).

20-05-2009 01:49 | Сообщение от автора вопроса
Прекратите писать вирусы!!!
Это смотря для чего вам это нужно.

Программа для обучения и контроля знаний.
Другие уже готовые, где это реализовано не предлагать.
Многие пользователи программы хотят иметь такую возможность, например чтобы для перевода чисел из одной системы счисления в другую без калькулятора или чтобы не открыли excel и не проверяли какая формула будет ... и т.д. (много было пожеланий).

20-05-2009 00:58
Прекратите писать вирусы!!!

19-05-2009 13:06 | Вопрос к автору: запрос дополнительной информации
Это смотря для чего вам это нужно.

19-05-2009 12:21
Это точно, 100% поможет.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure WMShowWindow(var Msg: TWMShowWindow); message WM_ShowWindow;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//Этот обработчик и избавит тебя от WIN+D
procedure TForm1.WMShowWindow(var Msg: TWMShowWindow);
begin
  if not Msg.Show then
    Msg.Result := 0
  else
    inherited;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  HTaskbar: HWND;
  OldVal: LongInt;
begin
  try
    HTaskBar := FindWindow('Shell_TrayWnd', nil);
    SystemParametersInfo(97, Word(True), @OldVal, 0);
    EnableWindow(HTaskBar, False);
    ShowWindow(HTaskbar, SW_HIDE);
  finally
    with Form1 do
      begin
      BorderStyle := bsNone;
      FormStyle  := fsStayOnTop;
      Left        := 0;
      Top        := 0;
      Height      := Screen.Height;
      Width      := Screen.Width;
    end;
  end
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  HTaskbar: HWND;
  OldVal: LongInt;
begin
  HTaskBar := FindWindow('Shell_TrayWnd', nil);
  SystemParametersInfo(97, Word(False), @OldVal, 0);
  EnableWindow(HTaskBar, True);
  ShowWindow(HTaskbar, SW_SHOW);
end;

end.


19-05-2009 11:32
так я и не понял как от WIN+D избавиться...

19-05-2009 10:29
Это должно помочь.

procedure TForm1.FormCreate(Sender: TObject);
var
  HTaskbar: HWND;
  OldVal: LongInt;
begin
  try
    HTaskBar := FindWindow('Shell_TrayWnd', nil);
    SystemParametersInfo(97, Word(True), @OldVal, 0);
    EnableWindow(HTaskBar, False);
    ShowWindow(HTaskbar, SW_HIDE);
  finally
    with Form1 do
      begin
      BorderStyle := bsNone;
      FormStyle  := fsStayOnTop;
      Left        := 0;
      Top        := 0;
      Height      := Screen.Height;
      Width      := Screen.Width;
    end;
  end
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
  HTaskbar: HWND;
  OldVal: LongInt;
begin
  HTaskBar := FindWindow('Shell_TrayWnd', nil);
  SystemParametersInfo(97, Word(False), @OldVal, 0);
  EnableWindow(HTaskBar, True);
  ShowWindow(HTaskbar, SW_SHOW);
end;


19-05-2009 10:16
+ таймер проверки состояния...
Зачем все эти фокусы? Если нужно запретить доступ к рабочему столу, то достаточно написать свой шелл и подменить им стандартный. Тогда при запуске винды в качестве рабочего стола будет ваша программа.

19-05-2009 09:15 | Комментарий к предыдущим ответам
М-дя... По закону жанра ждем следующего вопроса: Как можно свернуть полноэкранное приложение, которое не хочет сворачиваться?
:D

19-05-2009 07:44
А если два экземпляра программы? А если твой и другого программиста (столь же наголого)
Alt-Tab. Или кнопочки в панельке задач.

19-05-2009 06:51 | Вопрос к автору: запрос дополнительной информации
А если два экземпляра программы? А если твой и другого программиста (столь же наголого)

19-05-2009 06:30
а не достаточно из BorderIcons всё убрать?
Нет, не достаточно...:-) Проверьте сами.

19-05-2009 06:22
>>> От ярлыка "Показать рабочий стол" ничто не спасет
Это который "Свернуть все окна"? Вот тут про это ещё много было: »вопрос КС №42112«
А вообще верное замечание: не дело это.

P.S. To fox: а не достаточно из BorderIcons всё убрать?

19-05-2009 05:48
>>>От ярлыка "Показать рабочий стол" ничто не спасет.

+ таймер проверки состояния...

Не дадим пользователю нас одурачить!!!

19-05-2009 05:00
От ярлыка "Показать рабочий стол" ничто не спасет.

19-05-2009 04:54
В ObjectInspector ставим WindowState:= wsMaximized;

  TfmMain = class(TForm)
  ...
  private
    { Private declarations }
  protected
    procedure WMSysCommand(var Message:TWMSysCommand);message WM_SYSCOMMAND;
  public
    { Public declarations }
  end;


procedure TfmMain.WMSysCommand(var Message:TWMSysCommand);
begin
  if ((Message.CmdType and $FFF0) = SC_RESTORE) or
    ((Message.CmdType and $FFF0) = SC_MOVE) or
    ((Message.CmdType and $FFF0) = SC_MINIMIZE) then Message.Msg:=0
  else inherited;
end;


Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Однажды, в студеную зимнюю пору я из лесу вышел, был сильный ЧТО?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования