| 
| 
 | Вопрос # 6 555/ вопрос решён / | 
 |  Приветствую, уважаемые эксперты!Использую компонет Tchromium для загрузки сайтов, в файле dpr можно задать CefSingleProcess := false, если многоядерный запуск или
 CefSingleProcess := true если одноядерный запуск.
 Советуется ставить многоядерный запуск, типа так приложение стабильнее работает, но бывают компьютеры на которых наоборот одноядерный режим стабильнее работает, меньше оперативы используется и кэш реже повреждается, хочу чтобы перед запуском пользователь сам выбирал какой режим запуска использовать, каким образом посоветуете это реализовать?
 Если перед кодом инициализации движка кода поставить диалоговое окошко с выбором, то гуд работает при выборе одноядерного режима, а если выбрать там многоядерный режим то потом заново выполняется этот код несколько раз и их дофига открывается, пробовал проверку замутить через переменную, но нифига не катит, так как приложение запускается в нескольких потоках и в каждом она оказывается не заданная.
 
|  |   Вопрос задал: sergei (статус: Посетитель)Вопрос отправлен: 19 августа 2014, 14:09
 Состояние вопроса: решён, ответов: 0.
 |  
 Мини-форум вопросаВсего сообщений: 13; последнее сообщение — 19 августа 2014, 22:15; участников в обсуждении: 2. 
|   | min@y™ (статус: Доктор наук), 19 августа 2014, 17:38 [#1]:CefSingleProcess - это что, глобальная переменная? 
 Цитата (sergei): Если перед кодом инициализации движка кода поставить диалоговое окошко с выбором, то гуд работает при выборе одноядерного режима, а если выбрать там многоядерный режим то... Пока понятно, до этого места, но дальше как-будто писал другой человек:
 
 Цитата (sergei): ...потом заново выполняется этот код несколько раз и их дофига открывается, пробовал проверку замутить через переменную, но нифига не катит, так как приложение запускается в нескольких потоках и в каждом она оказывается не заданная. Просто дай посмотреть dpr и всё.
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | sergei (статус: Посетитель), 19 августа 2014, 18:00 [#2]:program Browser; 
 uses
 System.sysutils,
 ceflib,
 vcl.controls,
 Winapi.Windows,
 SyncObjs,
 Vcl.Forms,
 vcl.dialogs,
 Vcl.Themes,
 Vcl.Styles,
 main in 'main.pas' {MainForm},
 startUnit in 'startUnit.pas' {startForm};
 
 {$R *.res}
 {$R 'my_manifest.res' 'my_manifest.rc'}
 
 
 begin
 Application.Initialize;
 TStyleManager.TrySetStyle('Metropolis UI Blue');
 Application.CreateForm(TstartForm, startForm);
 startForm.ShowModal;
 if startform.ComboBox1.ItemIndex=1 then
 CefSingleProcess := false else CefSingleProcess := true;
 startform.Free;
 CefCache := 'Cache';
 CefUserAgent :='Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36';
 if not CefLoadLibDefault then Exit;
 CookieManager := TCefCookieManagerRef.Global;
 CookieManager.SetStoragePath('Cache\', true);
 Application.MainFormOnTaskbar := True;
 Application.CreateForm(TMainForm, MainForm);
 Application.Run;
 end.
 
 Когда CefSingleProcess = false то выполняется код в файле dpr по 8-10 раз, приложение становиться многопроцессорным, и поэтому окошко startForm.ShowModal появляется после первого выбора еще много раз, CefSingleProcess вроде как глобальные переменная из модуля ceflib, но она в каждом потоке заново присваивается.
 |  
|   | sergei (статус: Посетитель), 19 августа 2014, 18:19 [#3]:Чуть помогает способ если писать на диск файл в событии onshow диалогового окошка, и в файле dpr добавить проверку if not fileexists('testzapusk') then отобразить окошко, но потом нужно найти момент когда этот файл удалить, то что в многопроцессорном режиме этот код может и еще выполнится через минут 5 там не угадаешь. |  
|   | min@y™ (статус: Доктор наук), 19 августа 2014, 18:41 [#4]: Цитата (sergei): Когда CefSingleProcess = false то выполняется код в файле dpr по 8-10 раз, приложение становиться многопроцессорным, и поэтому окошко startForm.ShowModal появляется после первого выбора еще много раз Просто приложение запускает само себя (свои копии), так сам google chrome работает (каждая вкладка - новый процесс). Именно поэтому и появляется окошко выбора твоё - из нового процесса.
 
 Цитата (sergei): CefSingleProcess вроде как глобальные переменная из модуля ceflib, но она в каждом потоке заново присваивается.  Да глобальная, но только внутри процесса, а не системы! Для каждого из процессов она своя!
 
 Цитата (sergei): Чуть помогает способ если писать на диск файл в событии onshow диалогового окошка, и в файле dpr добавить проверку if not fileexists('testzapusk') then отобразить окошко, но потом нужно найти момент когда этот файл удалить, то что в многопроцессорном режиме этот код может и еще выполнится через минут 5 там не угадаешь.  Не надо файлов. Есть другие способы узнать при запуске, что данная копия приложения - не единственная в памяти (заголовки окон, мьютексы, а ещё лучше - семафоры).
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | sergei (статус: Посетитель), 19 августа 2014, 18:55 [#5]:Спасибо, раньше с этими объектами никогда не работал, поэтому сперва придется вникнуть, о результатах позже отпишу. |  
|   | sergei (статус: Посетитель), 19 августа 2014, 20:12 [#6]:Через мьютекс с именем приложения реализовал таким образом hMutex := CreateMutex(nil, False, Pchar(ExtractFileName(Application.ExeName)));
 CreateMutexResult :=
 (GetLastError = ERROR_ALREADY_EXISTS) or (hMutex = 0);
 if CreateMutexResult then begin
 if not CefLoadLibDefault then Exit;
 end else begin
 TStyleManager.TrySetStyle('Metropolis UI Blue');
 Application.CreateForm(TstartForm, startForm);
 startForm.ShowModal;
 if startform.ComboBox1.ItemIndex=1 then
 CefSingleProcess := false else CefSingleProcess := true;
 startform.Free;
 end;
 
 В итоге диалоговое окошко появляется один раз как нужно, запускается программа корректно, но после закрытия приложения  выдает сообщение с ошибкой Runtime error 216 at 00407946.
 |  
|   | sergei (статус: Посетитель), 19 августа 2014, 20:36 [#7]:Спасибо, ошибка оказалась в другом месте, еще до моих других экспериментах решения проблемы, в сам модуль ceflib полез, что привело к такой ошибке, откатил и сейчас работает как задумано) |  19 августа 2014, 20:38: Статус вопроса изменён на решённый (изменил автор вопроса — sergei): Помогли советы эксперта. 
|   | min@y™ (статус: Доктор наук), 19 августа 2014, 20:49 [#8]:Я больше не буду читать куски кода без подсветки, комментариев и форматирования. Глаза болят. 
 Сделай по-человечески.
 
  
hMutex := CreateMutex(nil, False, Pchar(ExtractFileName(Application.ExeName)));
CreateMutexResult := (GetLastError = ERROR_ALREADY_EXISTS) or (hMutex = 0);
 
if CreateMutexResult
  then begin
         if not CefLoadLibDefault
           then Exit;
       end
  else begin
         TStyleManager.TrySetStyle('Metropolis UI Blue');
         Application.CreateForm(TstartForm, startForm);
         startForm.ShowModal;
 
         if startform.ComboBox1.ItemIndex=1
           then CefSingleProcess := false
           else CefSingleProcess := true;
 
          startform.Free;
        end;Если есть hMutex:= CreateMutex(...), то где CloseHandle(hMutex)?
 Что означает условие (GetLastError = ERROR_ALREADY_EXISTS) or (hMutex = 0)?
 
 Не копипасть всякую херню из интернетов, не разобравшись, для чего она и как работает. Комментарь каждую строчку, я, блин, не телепат ниразу!
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | sergei (статус: Посетитель), 19 августа 2014, 21:03 [#9]:Там в CreateMutexResult я получаю булево значение истина если мьютекс равен 0, то есть не создан, и ложь если не равен 0, то есть создан, потом отображаю диалоговое окошко когда истина, потому что второй раз мьютекс не создается, насчет деинициализации мьютекса я думал, но это тоже самое будет как определить в какой момент удалить файл, что до этого способ у меня был, по правилам да нужно по окончанию дописать ReleaseMutex(hMutex); CloseHandle(hMutex); и толку тогда будет от этого мьютекса, он будет обнулен и в следующем экземпляре сново запустится диалоговое окошко. |  
|   | sergei (статус: Посетитель), 19 августа 2014, 21:22 [#10]:Насчет (GetLastError = ERROR_ALREADY_EXISTS) то эта глобальная переменная в которую пишется последняя ошибка, и при повторном создании мьютекса в нее записывается ошибка ERROR_ALREADY_EXISTS, благодаря чему не появляется повторно диалоговое окно. |  
|   | min@y™ (статус: Доктор наук), 19 августа 2014, 21:34 [#11]: Цитата (sergei): если мьютекс равен 0, то есть не создан Хэлп по функции ты не читал.
 
 Цитата: Return Values
 
 If the function succeeds, the return value is a handle to the mutex object. If the named mutex object existed before the function call, the GetLastError function returns ERROR_ALREADY_EXISTS. Otherwise, GetLastError returns zero.
 If the function fails, the return value is NULL. To get extended error information, call GetLastError.
 
 
 Цитата (sergei): Насчет (GetLastError = ERROR_ALREADY_EXISTS) то эта глобальная переменная в которую пишется последняя ошибка Да ты что?!!! Правда-правда????!!!!1111 Вот блять, а я-то всю жизнь думал, что это функция... Расходимся, нас наебали...
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | sergei (статус: Посетитель), 19 августа 2014, 22:09 [#12]:Сам спросил про это, я тебе написал что она делает в моем случае, а что возвращает значение последнего неудачного Windows API вызова, эт само собой. На счет в представленной справке по мьютексу я не понял, о чем там сказано, что я не так сделал? В справке красными буквами сказано, что в случае провала мьютекс равен 0, поэтому у меня написано если мьютекс равен 0 значит он не создан, точнее если быть, то повторно не создан в моем случае. |  
|   | min@y™ (статус: Доктор наук), 19 августа 2014, 22:15 [#13]:Понятно. Оно мне надо?
 Проехали.
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |