|
Вопрос # 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. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|