Логин: Пароль:    Регистрация Всеми возможностями сайта можно пользоваться
только после авторизации.
   Забыли пароль?

Поиск
L



Статистика
u
Пользователи онлайн: нет
Гостей онлайн: 3
Всего онлайн: 3
Зарегистрировано юзеров: 6705
Комментариев на сайте: 651
Новый юзер: RavBroaft



Последние комментарии
c
Rodneyhef прокомментировал "Урок 53 - Потоки в Delphi, (часть 1/3)":
Zauważże, czym cechują się kredyty na sześcdziesięciu dni. Jako co zwrócić uwagę podczas asortymentu oferty? Które firmy użyczają chwilówek za taki czas? Sprawdź! [url=https://chwilowki-pozyczka.pl/]chwilówki[/url] [url=https://chwilowki-pozyczka.pl/chwilowki-online]chwilówki online[/url] [url=https://chwilowki-pozyczka.pl/pozyczki-na-raty]pożyczki ratalne[/url] [url=https://chwilowki-pozyczka.pl/kredyty-gotowkowe]kredyty gotówkowe[/url] Zdecydowana większość pożyczek krótkoterminowych udzielana jest od okres nie zaakceptować dłuższy niźli dwa miesiące. Krótki słowo spłaty wydaje się być charakterystyczny na rzecz tego rodzaju wytworów finansowych. Firmy pożyczkowe wprowadziły także zastrzeżenia, skutkujące tym, że nie każdy klient będzie mógł momentalnie zaciągnąć wzięcie pożyczki na 60 dni. W poniższym artykule podpowiadamy, na jak zwrócić uwagę, postanawiając się pod ten typ dofinansowania, na czym polegają opisane ograniczenia, oraz pokazujemy, które obecne na rynku firmy użyczają pożyczek dzięki 60 dni. chwilowki-pozyczka.pl Termin kredyty jest jednym z kluczowych składników mających bezpośredni wpływ jako całkowite koszty zobowiązania. Alternatywa krótszego czy dłuższego sezonu ma przełożenie na wysokość RRSO, innymi słowy rzeczywistej rocznej stopy oprocentowanie informującej nas w stosunku procentowym o kosztach związanych z pożyczką. Jest to pierwszy element, na który trzeba zwrócić szczególną uwagę w chwili wyboru możliwości. Drugim elementem jest uważna ocena spersonalizowanych możliwości kredytowych, co koniecznie musi towarzyszyć zaciąganiu jakiegokolwiek zobowiązania. Być może będziemy potrzebować produktu finansowego, którego spłata wydaje się znacznie dłuższa. Wówczas winniśmy zdecydować się jako pożyczki od raty. Warto również stwierdzić o aplikowanych przez spółki pożyczkowe ograniczeniach, wynikających spośród realizacji strategii ryzyka. Ochraniając się zanim niewypłacalnością pożyczkobiorców, instytucje finansowe przedłożyły szereg wielu ograniczeń, oddanych w szczególności dla osób nowych odbiorców. Ci pożyczkobiorcy, którzy zaciągają chwilówkę na raz 1 w podanej firmie, niejednokrotnie nie mogą liczyć na termin dłuższy niźli 30 dni. Poza tym wiążą ograniczenia szczególne dla kredytów krótkoterminowych. Przemówienie między innymi na temat weryfikacji petentów w charakteryzujących się ogromną popularnością rejestrach dłużników, ukończenie 21. roku egzystencji czy identyfikacja maksymalnej poziomie pożyczki. Pożądane byłoby podkreślić, hdy znaczna część przedsiębiorstw nie udziela pożyczek o dłuższym okresie w ogóle, co ponadto nie jest rezultatem wprowadzenia ograniczeń, a wynika po prostu wraz z oferty.
dealrattKi прокомментировал "Урок 3 - Конструкция IF...THEN...ELSE":
Это действительно радует меня. --- Бесподобное сообщение скачать fifa, скачать фифа а также [url=http://15fifa.ru/novosti-fifa-15]fifa 15 последние новости[/url] скачать фифа

Ограничение количества одновременно запущенных экземпляров приложения

Обсуждение данной темы ведется, начиная с появления первых 32-х разрядных версий Windows. Казалось бы, проблема давно уже должна быть окончательно решена, но количество вопросов в конференциях и форумах не уменьшается, хотя из книги в книгу, из FAQ'а в FAQ кочуют одни и те же варианты решения. Но не все так очевидно и просто.

Определим требования, которым должно удовлетворять решение для того, что бы его можно было использовать в большинстве случаев. Очевидно, что способ должен:

  • работать во всех версиях ОС;
  • быть надежным;
  • достаточно универсальным;
  • простым в реализации;
  • не давать побочных эффектов.
Каким образом можно поступить? На ум сразу приходит решение «в лоб»: почему бы не просмотреть список всех запущенных в системе процессов и не определить, запущен ли уже наш исполняемый модуль? Но почему-то именно этот «очевидный» способ практически никогда не используется. Для получения списка процессов в Windows 9X используются функции ToolHelp, а в Windows NT – PSAPI. То есть для разных версий Windows и алгоритмы разные. Оставим этот способ для отладочных средств и просмотрщиков…

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

Раз «в лоб» нельзя, то остается стандартный способ – при запуске приложения проверить какой-то уникальный признак и, если он не установлен, то установить, а после завершения работы сбросить. Именно так на практике обычно и поступают. Кандидатов на роль уникального признака довольно много, но не все одинаково пригодны для нашей задачи. Например, не лучшим решением будет использовать глобальные атомы. В случае аварийного завершения приложения, когда явно не вызывается GlobalFreeAtom, они имеют неприятную особенность оставаться в системе до ее перезагрузки. По той же причине абсолютно неприемлемы: создание или попытка открытия какого-либо файла, использование реестра и т.п. Лучшими кандидатами остаются объекты ядра – они просты в использовании, быстры, счетчик ссылок на объект, как правило, декрементируется даже при аварийном завершении процесса. Чаще всего это Mutex и FileMapping.

Типичный код выглядит так:
program MyProgram;
uses
  Windows,
  Forms,
  MyUnit in 'MyUnit.pas' {Form1};

{$R *.RES}

var
  Mutex : THandle;
begin
  Mutex := CreateMutex(nil, False, ‘MyMutex’);
  if Mutex = 0 then
    MessageBox(0,'Невозможно создать мьютекс', 'Ошибка',
      MB_OK or MBICONSTOP)
  else if GetLastError = ERROR_ALREADY_EXISTS then
    MessageBox(0,'Программа уже запущена', 'Ошибка',
      MB_OK or MBICONSTOP)
  else
  begin
    Application.Initialize;  
    Application.CreateForm(TForm1, Form1);
    Application.Run;
    CloseHandle(Mutex);
  end;
end.
В приведенном коде все же есть один дефект. Он никогда не проявится в приложениях типа «Hello World!”, но может привести к очень неприятным последствиям в приложениях серьезных. Я имею в виду инициализацию, которая происходит до процедуры проверки при загрузке модулей. Она так же может занимать достаточно много времени. В этих случаях также возможен запуск нескольких экземпляров приложения, что в некоторых случаях может привести к конфликтам доступа и нехватке ресурсов (из-за чего, собственно говоря, чаще всего проверка и производится). Даже если этого и не произойдет, производится бесполезная работа. Отсюда вывод: процедуру проверки необходимо производить как можно раньше, до начала всех инициализаций, и в случае неудачи немедленно завершать приложение. Для этого помещаем процедуру проверки в отдельный модуль, который указываем в списке используемых проектом модулей ПЕРВЫМ:
program MyProgram;
uses
  OneHinst;  
  Windows,
  Forms,
  MyUnit in 'MyUnit.pas' {Form1};

{$R *.RES}

begin
    Application.Initialize;  
    Application.CreateForm(TForm1, Form1);
    Application.Run;
end.

unit OneHinst;
interface

implementation
uses
  Windows;
var
  Mutex : THandle;
  MutexName : array[0..255] of Char;

function StopLoading : boolean;
var
  L,I : integer;
begin
  // В качестве уникального имени мьютекса используем полный путь
  // к исполняемому файлу приложения
  L := GetModuleFileName(MainInstance,MutexName,SizeOf(MutexName));
  // В имени мьютекса нельзя использовать обратные слэши, поэтому
  // заменяем их на прямые
  for I := 0 to L - 1 do
    if MutexName[I] = '\' then
    begin
      MutexName[I] := '/';
    end;
  Mutex := CreateMutex(nil,false,MutexName);

  Result := (Mutex = 0) or // Если мьютекс не удалось создать
  (GetLastError = ERROR_ALREADY_EXISTS); // Если мьютекс уже существует
end;

procedure ShowErrMsg;
const
  PROGRAM_ALREADY_RUN = 'Невозможно запустить программу';
begin
  MessageBox(0,PROGRAM_ALREADY_RUN,MutexName, MB_ICONSTOP or MB_OK);
end;

initialization
  if StopLoading then
  begin
    ShowErrMsg;
    // Так как никаких инициализаций еще не производилось, то
    // спокойно используем для завершения программы Halt -
    // finalization все равно выполнится
    halt;
  end;
finalization
  if Mutex <> 0 then
    CloseHandle(Mutex);
end.
Напоследок еще пример: как ограничить количество одновременно исполняющихся экземпляров приложения
unit LimHinst;
//****************************************************************************
//
// Author: ©2001 Vladimir G. Yudin aka y-soft
// e-mail: y-soft@mail.ru
//
// Description: Ограничение количества одновременно работающих экземпляров 
// приложения.
//
// Отличие от существующих реализаций:
//
// 1. С целью исключения преждевременных инициализаций проверка
// производится в самом начале загрузки приложения, до загрузки всех модулей
// 2. Исключен возможный конфликт имен, т.к. в качестве уникального имени
// используется полный путь к исполняемому модулю
// 3. Изменением значения HinstLim можно установить любое разрешенное количество
// одновременно запущенных экземпляров приложения
// 4. Изменением WaitPause можно регулировать время ожидания 
// (если установить INFINITE, то получится своеобразный вариант горячего
// резервирования)
//
// Тестировалось в WinME и WinNT 4 SP6A. Ошибки не обнаружены
//
// Usage: модуль необходимо указать ПЕРВЫМ в списке uses файла .DPR проекта
// и установить необходимые значения констант HinstLimit и WaitPause.
//
// Возможные расширения:
//
// 1. Значения HinstLimit и WaitPause хранить в INI-файле или в реестре
// 2. Значение HinstLimit  менять динамически в зависимости от условий
//
// Thanks: Спасибо Юрию Зотову за указание на существование проблемы
//
// Disclaimer: Используйте совершенно свободно на свой страх и риск.
// Автор убедительно просит сообщать ему о найденных ошибках и
// внесенных усовершенствованиях.
// Всякие совпадения идей, наименований функций, процедур, переменных и
// констант считать случайными :)
//
//****************************************************************************
interface

const
   //Установите необходимые значения!!!
  HinstLimit = 1;
  WaitPause = 50;

implementation
uses
  Windows;
var
  Semaphore : THandle;
  SemaphoreName : array[0..255] of Char;
  IncCnt : integer;

function StopLoading : boolean;
var
  L,I : integer;
begin
  // В качестве уникального имени семафора используем полный путь
  // к исполняемому файлу приложения (по определению уникален!!!)
  L := GetModuleFileName(MainInstance,SemaphoreName,SizeOf(SemaphoreName));
  // В имени семафора нельзя использовать обратные слэши, поэтому
  // заменяем их на прямые (или еще на что-нибудь кроме #0)
  for I := 0 to L - 1 do
    if SemaphoreName[I] = '\' then
      SemaphoreName[I] := '/';

  Semaphore := CreateSemaphore(nil,HinstLimit,HinstLimit,SemaphoreName);

  Result := (Semaphore = 0) or // Если семафор не удалось создать
  (WaitForSingleObject(Semaphore,WaitPause) <> WAIT_OBJECT_0); // Если семафор занят
end;

procedure ShowErrMsg;
const
  PROGRAM_ALREADY_RUN = 'Лимит исчерпан';

begin
// Главное окно программы еще не существует, поэтому выводим MessageBox 
// без владельца 
 MessageBox(0, PROGRAM_ALREADY_RUN, SemaphoreName, MB_ICONSTOP or 
MB_OK);
end;

initialization
  IncCnt := 0;
  if StopLoading then
  begin
    ShowErrMsg;
    // Так как никаких инициализаций еще не производилось, то
    // спокойно используем для завершения программы Halt -
    // finalization все равно выполнится
    halt;
  end
  else
    IncCnt := 1;
finalization
  if Semaphore <> 0 then
  begin
    // Обязательно явно освобождаем семафор, т.к.
    // автоматически его счетчик ссылок не переустанавливается
    ReleaseSemaphore(Semaphore, IncCnt, nil);
    // Напоследок во избежание неожиданностей освобождаем дескриптор семафора
    // (так предписывает MSDN)
    CloseHandle(Semaphore);
  end;
end.

Вот и всё, Удачи!

Используйте конвертирование PDF в Excel
Источник: thedelphi.ru
Автор: Савельев Александр
Опубликовано: 22 Ноября 2015
Просмотров:


Зарегистрируйтесь или авторизуйтесь, чтобы добавлять комментарии.